动画轮播.

var imgs=[
	{"i":0,"img":"images/index/banner_01.jpg"},
	{"i":1,"img":"images/index/banner_02.jpg"},
	{"i":2,"img":"images/index/banner_03.jpg"},
	{"i":3,"img":"images/index/banner_04.jpg"},
	{"i":4,"img":"images/index/banner_05.jpg"},
];

//面向对象   封装广告轮播所需的全部属性和方法
var 	slider={
	LIWIDTH:0,//保存每一个li的宽度
	$parent:null,  //保存轮播的父元素
	$imgs:null,  //保存轮播的ul imgs	元素
	$indexs:null,  //保存轮播的ul  indexs 元素
	DURATION:1000,  //每次轮播的总时间
	WAIT:3000,   //每次自动轮播之间的时间间隔
	timer:null,  //保存自动轮播的定时器序号
	canAuto:true,   //保存是否可启动自动轮播,使鼠标已进入div就结束动画
	init:function($parent){  //-------->传入的是document下的div 须要$ 封装
		this.$parent=$parent;
		this.$parent.addClass("slider");
		/*
		jq:2步建立	
		*/
		this.$imgs=$("<ul class='imgs'></ul>");
		this.$indexs=$("<ul class='indexs'></ul>");
		this.$parent.append(this.$imgs);
		this.$parent.append(this.$indexs);
		this.LIWIDTH=parseFloat(this.$parent.css("width"));
		this.$imgs.css("width",this.LIWIDTH*imgs.length);
		this.updateView();  //在ul中动态生成元素
		this.myBind();		//绑定全部事件
		this.autoMove();  //一开始就启动自动轮播
	},
	
	//全部事件的绑定
	myBind:function(){
		//为$indexs绑定mouseover,只有li能响应事件
		//  $("parent").on("事件名","selector",fn)
		this.$indexs.on("mouseover","li",this,
			function(e){//  e.data-->slider     由于对象on事件绑定的是li
				var $this=$(this);  //this--->当前li  传入的on事件须要使用的数据e.data=this  
											 // e.data 是on事件 绑定的第三个参数 固定名词
											//这里的this 也是指的是 	this.$indexs.on  $index ·前的this  不就是slider
				//若是当前li没有hover
				if(!$this.hasClass("hover")){
					//用当前li的内容-当前li的兄弟中class为hover的li的内容,保存在变量n中
					e.data.move(
						$this.html()-$this.siblings("li.hover").html()  
					/*
					上一步得出的结果是  
					经过下标的移动来计算下标的差值
					得出this.move须要的n值
					*/
					);
					//调用this.move(n)
				}
		}); 
		//为$parent绑定hover事件为
		//设置进入div  就中止自动轮播,利用中间参数canAuto
		this.$parent.hover(
			function(){
			clearTimeout(this.timer);
			this.timer=null;
			this.canAuto=false;
		}.bind(this),
			function(){
			this.canAuto=true;
			this.autoMove();
		}.bind(this)
		)
	},

	//启动一次自动轮播
	autoMove:function(){
		/*启动一次性定时器,设置任务函数为move,提早绑定this和1,
		设置时间间隔为WAIT,将序号保存在timer中*/
		this.timer=setTimeout(
			this.move.bind(this,1),this.WAIT
			);	
	},

	//计算目标位置,启动动画,n参数表示要移动的个数
	move:function(n){
			//中止$imgs上全部动画,不会出现动画叠加的状况
			this.$imgs.stop(true);
		if(n>0){//左移		
			/* $("...").animate({css属性: 目标值},speed, easing,callback)*/
			this.$imgs.animate(
				{left:-n*this.LIWIDTH},
				this.DURATION,
				//在动画结束后修改数组,更新数组
				this.changeImgs.bind(this,n)
				);
			//注意:对于动画animate,在回调函数中,使用的this对象,就是animate.前的$对象
			//即this.changeImgs---->this--->$imgs
			//而后用bind()绑定,由于bind只能绑定页面中存在的对象,因此经过bind(this)
			//咱们将this对象改成slider
		}else{//右移
			//先移动数组,更新界面
			this.changeImgs(n);
			//再次启动动画
			//由于是向右移动,因此这里咱们将无论最后其余img的位置
			//最后显示的那张img的left 确定是0
			this.$imgs.animate({left:0},this.DURATION);
		}
	},
	
	//修改数组,更新界面
	changeImgs:function(n){
		if(n>0){//左移
		//this--->slider
		//删除imgs数组开头的n个元素,在拼接到结尾
		imgs=imgs.concat(imgs.splice(0,n));
		//调用updateView
		this.updateView();//更新页面
		//$imgs的left归0
		this.$imgs.css("left",0);
		}else{//右移
			/*******重点*******/
			n*=-1;  //将n变为正数
			//删除imgs数组结尾的-n个元素,拼接到数组开头
			imgs=imgs.splice(imgs.length-(n),n)
								.concat(imgs);
			this.updateView();//更新页面
			//得到$imgs当前的left值-n*this.LIWIDTH,保存在新的left中
			var left=parseFloat(this.$imgs.css("left"))-n*this.LIWIDTH;
			this.$imgs.css("left",left);
		}
		//调用autoMove再次启动自动轮播
		if(this.canAuto) //设置自动轮播条件
			this.autoMove();
	},
	//向建立的两个ul中动态添加内容
	updateView:function(){
		for(var i=0,liImgs="",liIdxs="";i<imgs.length;i++){
			liImgs+="<li><img src='"+imgs[i].img+"'></li>";
			liIdxs+="<li>"+(i+1)+"</li>";
		}
		this.$imgs.html(liImgs);
		this.$indexs.html(liIdxs);
		//下标匹配  当前图片
		this.$indexs.children("li:eq("+imgs[0].i+")").addClass("hover");
	}
}


//$("#slider").slider();
//向jquery对象的原型中添加slider插件函数
$.fn.slider=function(){
	//最小知道原则  
	//让slider对象在当前父元素中初始化广告轮播功能
	slider.init(this);    //this->$("#slider")
}
相关文章
相关标签/搜索