无线端webapp图片轮转图

可以无限循环,到达最大页时,自动轮换到第0个,能实现无限循环。。
1、手指跟随和不跟随 isFollow
2、自动轮换  loop
3、是否延迟加载加载 lazyLoad

话不多说,请看源码:zepto.touchCarousel.js


(function($){
 /**
 *css3 Touch Scroll
 *
 * @author: zhangnan
 * 
 * @param	{Object}	options;
 * @config   {zepto}     options.$el    		//外围容器 选择器或者element
 * @config	 {array}     options.pages			//填充每一页的内容 Element || string || function
 * @config	 {Number}    options.animTime	 //动画时间,默认为500	
 * @config	 {Function}  options.beforechange //动画完成之前回调函数	
 * @config	 {Function}  options.afterchange //动画完成之后回调函数	
 * @isFollow {Boolean}	obtions.isFollow	 //是否跟随,默认false
 * @isFollow {Boolean}	obtions.loop	 //自动循环的时间/ms
 * 
 * 
 * 
 * 
 */

var TouchScroll=function(options){
	this.$el= $(options.$el);
	this.options= $.extend(arguments.callee.defaultData, options);
	this.options._lazyLoad= !this.options.loop && this.options.lazyLoad;
	this._wrapLeftIndex= this.options._wrapLeftIndex;
	this._curIndex= this.options._curIndex;
	this._initContainer();
	this._initNodes();
	this._init();
};

//默认参数
TouchScroll.defaultData= {
		isFollow: false,
		animTime: 500,
		_curIndex: 0,		//当前索引
		_wrapLeftIndex: 0,		//是外围动画节点的移动单位距离
		loop: 0,
		loopDir: 1,
		pages: [],
		lazyLoad: false,
		beforechange: function(){
			console.log('berore');
		},
		afterchange: function(){
			console.log('afterchange');
		},
}

$.extend(TouchScroll.prototype,{

	//顾名思义
	_init:function(){
		var self=this;
		self.touchEnabled= true;
		addEventListener('onorientationchange' in window ? 'orientationchange' : 'resize', function(e){
		});
		this.options.isFollow ? this.initTouchFollow() : this.initTouch();
		
		if(this.options.loop){
			var dirfoo= self.loopDir > 0 ? 'toLeft' : 'toRight';
			(self.autoLoop= function(){
				self.timeout= setTimeout(function(){
					self[dirfoo]();
				}, self.options.loop)
			})();
		}
		this.$container[0].addEventListener('webkitTransitionEnd', self, false);
		return this;
	},

	_initContainer: function(){ 
			this.$el.css({'overflow': 'hidden'});
			this._contentWidth= this.$el[0].clientWidth;
	},

	_initNodes: function(){
		var i= 0, nodes, length, left, contentWidth= this._contentWidth, self= this,
			reg= /<\//g,
			html= this.$el.html(); 
			
		if(this.options._lazyLoad)
			reg= /<\//;
		html= html.replace(reg, function($a){
			return self.getpage(i++)+$a
		});
		this.$el.html('<div  style="display: -webkit-box;-webkit-user-select: none;-webkit-transition: -webkit-transform '+this.options.animTime+'ms cubic-bezier(0, 0, 0.25, 1)">'+
				html
		+
		'</div>');
		nodes= this.nodes= (this.$container= this.$el.children()).children();
		
		this.maxIndex= (length= this.nodesLength= nodes.length) -1;
		var bestDest= Math.ceil(length/2);
		var nodesAry= self._nodes=[];
		nodes.forEach(function(node, index){
			left= index< bestDest ? index :  -(length- index);
			nodesAry.push({node: node, left: left, index: index});
			node.style.cssText+= ';-webkit-transform: translate(-'+(index)+'00%, 0) translate3d('+left*contentWidth+'px, 0px, 0px);  100%;';
		})
		nodesAry.sort(function(a, b){
			return a.left- b.left;
		});
	},

	_setNodesTranslate: function(dir){
		var into,
			out,
			bestLeft,
		   	nodes= this._nodes,
		   	node,
		   	contentWidth= this._contentWidth,
		   	maxIndex=this.nodesLength-1,
			curIndex= this._curIndex,
			curpage;
		if(dir==0)
			return;
		if(dir<0){
			into= 'unshift';
			out= 'pop';
			bestLeft= nodes[0].left -1;
		}else{
			into= 'push';
			out= 'shift';
			bestLeft= nodes[maxIndex].left+ 1;
		}
		node= nodes[out]();
		node.left= bestLeft;
		nodes[into](node);
		node.node.style.cssText= node.node.style.cssText.replace(/translate3d\(([-\d]+)px/g, 'translate3d\('+
					bestLeft* contentWidth
				+'px');
		if(this.options._lazyLoad){
			curpage= this.nodes[curIndex];
			!curpage.firstElementChild && (curpage.innerHTML= this.getpage(curIndex));
		}
	},

	toLeft: function(dir){

		this.move(-1);
	},

	toRight: function(){
		this.move(1);
	},

	toCurrent: function(){
		this.move(0);
	},

	getpage: function(index){
		var page= this.options.pages[index];
		return $.isFunction(page) ? page() : page instanceof Element ? page.outerHTML : page;
	},


	handleEvent: function(e){
		if(e.type==='webkitTransitionEnd'){
			this.options.afterchange(this._curIndex);
			this.touchEnabled= true;
			this.options.loop && this.autoLoop();
		}
	},

	move: function(dir){
		var left= this._wrapLeftIndex= this._wrapLeftIndex-dir, res;
		this._curIndex= (res= this._curIndex+ dir) < 0 ? this.maxIndex : res > this.maxIndex ? 0 : res;
		this._setNodesTranslate(dir);
		this.options.beforechange(this._curIndex);
		this.setLeft(left * this._contentWidth);
	},

	setLeft: function(left){
		this.$container.css({'-webkit-transform': 'translate3d('+ left +'px, 0px, 0px)'});
	},

	setAnimTime: function(time){
		this.$container.css('-webkit-transition', '-webkit-transform '+time+'ms cubic-bezier(0, 0, 0.25, 1)');
	},

	//一看就懂
	touchEv:(function(){
		var isTouchPad = (/hp-tablet/gi).test(navigator.appVersion),
		hasTouch='ontouchstart' in window && !isTouchPad;
		return {
			hasTouch:hasTouch,
			START_EV:hasTouch ? 'touchstart' : 'mousedown',
			MOVE_EV:hasTouch ? 'touchmove' : 'mousemove',
			END_EV:hasTouch ? 'touchend' : 'mouseup'
		}
	})(),
	//不跟随动画注册
	initTouch:function(){
		var now=null,
			touch={},
			self=this,
			timeout,
			touchEv=this.touchEv;
		this.$el.on(touchEv.START_EV,function(e){	
			if(!self.touchEnabled)
				return ;
			
			if(e.touches.length!==1)
				return ;
	//		self.stopLoop();
			touch.x1= e.touches[0].clientX;
			touch.y1= e.touches[0].clientY;

			
			timeout=setTimeout(function(){
				timeout=null;
			},800);
		}).on(touchEv.MOVE_EV,function(e){

			if(!self.touchEnabled)
				return ;
			if(timeout){
				touch.x2= e.touches[0].clientX;
				touch.y2= e.touches[0].clientY;
				dir=self.swipeDirection(touch.x1,touch.x2,touch.y1,touch.y2);
				if(dir=='Left' || dir=='Right')
					e.preventDefault();	
			}
		})
		$(document).on(touchEv.END_EV,function(e){
			if(!self.touchEnabled)
				return;
			if(timeout && touch.x2 && Math.abs(touch.x1 - touch.x2) > 5){
				self.touchEnabled= false;
				if(dir=='Left'){
					self.toRight();
				}else if(dir=='Right'){
					self.toLeft();
				}
			};
			touch={};
		});
		return this;
	},
	//跟随动画注册
	initTouchFollow:function(){
		var touchEv=this.touchEv,
			self=this,
			scrolling=null,
			startX=0,
			startY=0,
			moveX=0,
			moveY=0,
			baseX=0,
			distX,
			newX,
		//	startTime,
			dir=0,
			currentLeft= 0,
			transX;

		this.$el.on(touchEv.START_EV,function(e){
			if(!self.touchEnabled && e.touches.length!=1)
				return ;
			if(!touchEv.hasTouch)
				e.preventDefault();
			self.setAnimTime(0);
//          self.stopLoop();
			scrolling=true;
			moveRead=false;
			startX=e.touches[0].clientX;	
			startY=e.touches[0].clientY;	
			baseX=startX;
			newX= self._wrapLeftIndex* self._contentWidth;
			//startTime=e.timeStamp;
			dir=0;
		}).on(touchEv.MOVE_EV,function(e){
			if(!scrolling || !self.touchEnabled)
				return ;
			var moveX=e.touches[0].clientX,
				moveY=e.touches[0].clientY;	
			if(moveRead){
				distX=moveX-baseX;
				self.setLeft(newX+=distX);
				dir= distX>0 ? 1 : -1;
				baseX=moveX;
			}else{
				var changeX=Math.abs(moveX-startX),
					changeY=Math.abs(moveY-startY);
				if((changeX/changeY)>1){
				  	e.preventDefault();
                    e.stopPropagation();
                    moveY= null;
					moveRead=true;
				}else if(changeY>5){
					scrolling=false;
                    moveY= null;
					self.setAnimTime(self.options.animTime);
				}
			};
		});
		
		$(document).on(touchEv.END_EV,function(e){
			setTimeout(function(){
//			  self.setLoop();  
			},100);
			if(!scrolling || !self.touchEnabled)
				return ;
			self.touchEnabled= false;
			scrolling=false;
			transX = baseX-startX;
			self.setAnimTime(self.options.animTime);
			if(transX > 50){
				self.toLeft(null, 300);
			}else if(transX < -50){
				self.toRight(null, 300);
			}else{
				self.toCurrent(100);
			}
			scrolling=
			startX=
			startY=
			moveX=
			moveY=
			baseX=
			distX=
			newX=
			dir=
		    transX=null;
		}).on(touchEv.START_EV, function(e){
//           self.stopLoop();  
        })
		return this;
	},

	swipeDirection:function(x1, x2, y1, y2){
	    var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2)
	    return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down');
	},
});

//添加到Zepto
$.fn.touchCarousel=function(options){
	options.$el	= this;
	var instance = new TouchScroll(options);
	return instance ;
} 

})(Zepto);

html部分 index.html

<html>
	<head>
		<title>
			carousel by 一只柯楠	
		</title>	
		<style type="text/css">
			*{
				-webkit-tap-highlight-color: rgba(0,0,0,0);
				-webkit-user-select: none;
				-webkit-touch-callout: none;
				-webkit-user-drag: none;
				padding: 0;
				margin: 0;
			}
			#carousel img{
				 420px;
			}
			#carousel {
				 420px;
				margin: 0 auto;
				border: 20px solid red;
			}
			#carousel div{
				background: red;
				min-height: 150px;
				position: relative;
			}
			#carousel div span{
				position: absolute;
				height: 100%;
				 100%;
				font-size: 80px;
				line-height: 400px;
				font-weight: bold;
				text-align: center;
			}	
		</style>
	</head>
	<body>
		<div id="carousel">
			<div></div>
			<div></div>
			<div></div>
			<div></div>
			<div></div>
			<div></div>
		</div> 
		<script type="text/javascript" src="zepto.js"></script>
		<script type="text/javascript" src="zepto.touchscroll.js"></script>
		<script type="text/javascript">
			var html= [], len= 6;
			for(var i=1; i<=len; i++){
				html.push('<a  href="javascript:void(0);" ><span>'+i+'</span><img  src="img/'+i+'.jpg"></a>');
			}
			$('#carousel').touchCarousel({
                                     : 5000,
								pages:html ,
								isFollow: true 
							}
						);
 
		</script>
	</body>
</html>

 。。。。欢迎吐槽

原文地址:https://www.cnblogs.com/webzhangnan/p/2908887.html