手机端轮播图

    手机轮播图如果使用margin-left属性,在手机端用的流畅度低,低配置的手机卡顿越明显。而transition与translate3d(x,y,z)在手机端流畅度较高,原因两者都是CSS3属性结合,启用GPU硬件加速,而marginLeft则会触发浏览器重绘、重排,极度消耗性能。aui/sui/mui的轮播图都是使用css3属性制作轮播图的(谷歌浏览器的调试工具可查看),由于别人插件体积太大了,所以借鉴别人的开发经验,自己写一个移动端的轮播图。

    注意:轮播图片的默认宽高比是1:0.58(H = W * 0.58),也可以自己定义比例。虽然不是这个比例的图片也能正常轮播,但是超出这个比例的部分会被fitImage(objDiv, objImg)函数隐藏掉。

index.html代码如下:

<!DOCTYPE html>
<html>
	<head>
		<title>手机轮播图</title>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
		<link rel="stylesheet" href="css/api.css" />

		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			body{
				height: 999px;
			}
			/*body{
				-webkit-overflow-scrolling: touch;
			}*/
			.wrap-slider{
				overflow: hidden;
				width: 100%;
				position: relative;
				/*touch-action: none;这个区域内不允许上下拖动,慎用*/
			}
			.slider-group{
				width: 10000%;/*总共100张,每张设置1%*/
				height: 100%;
				position: absolute;
				top: 0px;
				left: 0px;
			}
			.slider-group:after{
				content: '';
				display: block;
				clear: both;
			}
			.slider-item{
				width: 1%;
				height: 100%;
				float: left;
			}
			.slider-item a{
				display: block;
				height: 100%;
				overflow: hidden;
			}
			.slider-item img{
				width: 100%;
				display: inline-block;
			}
			
			
			.silder-dots{
				position: absolute;
				bottom: 0;
				left: 0;
				right: 0;
				padding:5px;
				text-align: center;
			}
			.silder-dots i{
				display:inline-block;
				width:6px;
				height:6px;
				background:rgba(255,255,255,0.5);
				box-shadow:0 0 3px rgba(0,0,0,0.2);
				margin:0 2px;
				border-radius:9px;
			}
			.active-dots{
				background:rgba(255,255,255,1) !important;
				background:rgba(255,0,0,1) !important;
			}
			.silder-nums {
				position: absolute;
				bottom: 0;
				left: 0;
				right: 0;
				padding: 5px;
				text-align: center;
			}
			.silder-nums span{
				background-color: rgba(0,0,0,.3);
				color: #fff;
				font-size: 11px;
				line-height: 11px;
				border-radius: 5px;
				display: inline-block;
				padding: 3px 6px;
				letter-spacing: 1px;
			}
			
			#slider{
				padding-top: 100%;
				/*图片轮播区域用padding-top作为响应式高度的设置,由宽高比1:1得出,不建议使用js设置的原因,浏览器渲染时,js设置是有时间延迟
				 padding在css设置宽高比,防止js没加载渲染页面时,图片区域没固定*/
			}
		</style>
	</head>
	<body>
		<div id="slider" class="wrap-slider">
			<ul class="slider-group">
				<li class="slider-item">
					<a href="javascript:void(0)"><!--http://www.baidu.com/-->
						<img src="img/slider1.jpg"/>
					</a>
				</li>
				<li class="slider-item">
					<a href="javascript:void(0)">
						<img src="img/slider2.jpg"/>
					</a>
				</li>
				<li class="slider-item">
					<a href="javascript:void(0)">
						<img src="img/slider3.jpg"/>
					</a>
				</li>
				<li class="slider-item">
					<a href="javascript:void(0)">
						<img src="img/slider4.jpg"/>
					</a>
				</li>
				<li class="slider-item">
					<a href="javascript:void(0)">
						<img src="img/slider5.jpg"/>
					</a>
				</li>
				<li class="slider-item">
					<a href="javascript:void(0)">
						<img src="img/slider6.jpg"/>
					</a>
				</li>
				<li class="slider-item">
					<a href="javascript:void(0)">
						<img src="img/slider7.jpg"/>
					</a>
				</li>
			</ul>
			<!--<div class="silder-dots">
				<i class="dots-active"></i>
				<i></i>
				<i></i>
			</div>-->
		</div>
		
		
		
		<script type="text/javascript" src="js/sliderProductDetail.min.js" ></script>
		<!--<script type="text/javascript" src="js/sliderProductDetail.js" ></script>-->
		<script>
			new sliderProductDetail({
				'id': '#slider',
				'time': 2000,
				'ratio':'1:1',//宽高比
				'isSlide':true, //是否轮播,默认值是false,不进行轮播
				'isNumShow':false //数字与圆点,默认值是false,显示圆点
			});
		</script>
		
	</body>
</html> 

sliderProductDetail.js未压缩的代码,有利于修改源码

/*制作轮播图要求:
 *1.padding在css设置宽高比,防止js没加载渲染页面时,图片区域没固定
 *2.js设置滑动区域上下滑动时,左右不滑动
 *3.当只有一张图片,就不允许左右滑动 
 *4.允许设置是数字或点
*/
function sliderProductDetail(obj){
	obj.time = obj.time || 1500;
	obj.time = Math.max(obj.time,1500);
	obj.ratio = obj.ratio || '1:0.58';//宽高比
	obj.ratio = parseFloat(obj.ratio.split(":")[0])/parseFloat(obj.ratio.split(":")[1]);
	obj.isSlide = obj.isSlide || false;
	obj.isNumShow = obj.isNumShow || false;
	
	var idTag = document.querySelector(obj.id);
	var GroupDOM = idTag.getElementsByClassName('slider-group')[0];
	var ItemDOM = GroupDOM.getElementsByClassName('slider-item');
	
	var htm1 = ItemDOM[0].cloneNode(true);//克隆
	//var htm2 = ItemDOM[ItemDOM.length-1].cloneNode(true);
	GroupDOM.appendChild(htm1);
	//GroupDOM.insertBefore(htm2,GroupDOM.childNodes[0]);
	idTag.style.height = oh + 'px';
	
	
	var ow = idTag.offsetWidth;
	var oh = ow / obj.ratio;
	var aDOM = idTag.getElementsByTagName('a');
	var imgDom = idTag.getElementsByTagName('img');
	
	for(var i = 0; i < aDOM.length; i++) {
		aDOM[i].style.width = ow + 'px';
		aDOM[i].style.height = oh + 'px';
		imgDom[i].setAttribute('onload','fitImgSliderMobile(this)');
		fitImgSliderMobile(imgDom[i]);
	}
	//导航点
	var sliderDots = document.createElement('div');
	if(!obj.isNumShow){
		sliderDots.className = 'silder-dots';
		var iStr = '';
		for(var i = 0 ; i < aDOM.length-1; i ++){
			iStr += '<i></i>';
		}
		sliderDots.innerHTML = iStr;
		idTag.appendChild(sliderDots);
		var iDots = sliderDots.getElementsByTagName('i');
	}else{
		sliderDots.className = 'silder-nums';
		var iStr = '<span>1/'+ (ItemDOM.length-1) +'</span>';
		sliderDots.innerHTML = iStr;
		idTag.appendChild(sliderDots);
	}
	transform3dX(0);
	setDotClass(0);
	
	var num = 0,timeToLeft = 350, setIval;
	var seTimeGroup = setTimeout(function(){//webkit
		var a = 'transform',b = 'cubic-bezier(0.165, 0.84, 0.44, 1)';
		GroupDOM.style.transitionProperty = a;
		GroupDOM.style.transitionTimingFunction = b;
		
		GroupDOM.style.webkitTransitionProperty = a;
		GroupDOM.style.webkitTransitionTimingFunction = b;
		
		transitionTime(2);
		clearTimeout(seTimeGroup);
	},1);
	if(aDOM.length==2){
		return;//当只有一张图片,就不允许左右滑动,不执行下面代码
	}
	function Ival(){ 
		if(obj.isSlide==false){
			return;
		}
		setIval = setInterval(function(){
			num ++;
			transitionTime(2);
			transform3dX(- num * ow);
			clearDotsClass();
			if(num < (ItemDOM.length - 1)){
				setDotClass(num);
			}
			if(num == (ItemDOM.length - 1)){
				setDotClass(0);
				var setTime = setTimeout(function(){
					num = 0;
					transitionTime(0);
					transform3dX(0);
					clearTimeout(setTime);
				},(2 * timeToLeft + 1));
				
				
				sliderAfter = false;
				var setTime2 = setTimeout(function(){
					sliderAfter = true;
					clearTimeout(setTime2);
				},2*timeToLeft+1);
			}
		},obj.time);
	}
	Ival();
	
	
	var startX=0 ,endX=0, startY=0, endY=0, startTime=0, endTime=0,  dVal = 0 , sliderAfter = true , swipeX , swipeY;
	idTag.addEventListener('touchstart', start, false);
	idTag.addEventListener('mousedown', start, false);
	
	document.addEventListener('touchend',end, false);
	document.addEventListener('mouseup',end, false);
	
	function start() {
		clearInterval(setIval);//清除定时器
		if(sliderAfter == false){
			return;
		}
		var e = event || window.event;
		startX = e.screenX || e.targetTouches[0].screenX;
		startY = e.screenY || e.targetTouches[0].screenY;
		startTime = new Date();
		swipeX = true;
     	swipeY = true ;
		document.addEventListener('touchmove',move, false);//添加侦听器
		document.addEventListener('mousemove',move, false);//添加侦听器
		document.ontouchmove = function() { //图片区域禁止浏览左右滑动
			return false;
		}
		clearTimeout(setTimeD);//必须清除这个定时器才能执行下面的判断条件,否则引发bug
	}
	
	function move(event){
		var e = event || window.event;
		endX = e.screenX || e.targetTouches[0].screenX;
		endY = e.screenY || e.targetTouches[0].screenY;
		dVal = endX - startX;//两点间的距离,也可以判断正负。
		
		if(swipeX && Math.abs(endX-startX)-Math.abs(endY-startY)>0) {//左右滑动
	        swipeY = false ;
	        event.stopPropagation();//阻止冒泡
	        event.preventDefault();//阻止浏览器默认事件
	        var x3d = Math.min((num * ow - dVal),(ow * (ItemDOM.length-1)));
			transitionTime(0);
			if(num == 0){
				x3d = Math.max(x3d,0);
			}
			if(num == ItemDOM.length-2){
				x3d = Math.min(x3d,(ow * (ItemDOM.length-2)));
			}
			transform3dX(-x3d);
	          
	    }else if(swipeY && Math.abs(endX-startX)-Math.abs(endY-startY)<0){  //上下滑动
	        swipeX = false ;//上下滑动,使用浏览器默认的上下滑动
	        document.ontouchmove = null; //图片区域恢复浏览左右滑动
	    }
	}
	function end(e) {
		clearInterval(setIval);//复活定时器前,必有清除之前存在的定时器,否则定时器会叠加,从而引发bug(num数字大于ItemDOM.length - 1)
		Ival();//复活定时器
		document.removeEventListener('touchmove',move, false);//删除侦听器
		document.removeEventListener('mousemove',move, false);//删除侦听器
		document.ontouchmove = null; //图片区域恢复浏览左右滑动
		endTime = new Date() - startTime;
		var e = event || window.event;
		endX = e.screenX || e.changedTouches[0].screenX;
		endY = e.screenY || e.changedTouches[0].screenY;
		if(30<endTime && endTime < 280 && swipeX){
			timeD();
		}else if(endTime >= 280){
			endUp();
		}
		startX=0 ,endX=0, startY=0, endY=0, startTime=0, endTime=0, dVal = 0;
	}
	
	var setTimeD;
	function timeD(){
		if(dVal<0 && dVal != 0){
			num ++;
			if(num==ItemDOM.length-1){
				num = ItemDOM.length - 2;
			}
		}else if(dVal>0 && dVal != 0){
			num -- ;
			if(num < 0){
				num = 0;
			}
		}
		transitionTime(1);
		transform3dX(-num * ow);
		clearDotsClass();
		setDotClass(num);
	}
	
	function endUp(){
		if(sliderAfter == false){
			return;
		}
		transitionTime(1);
		var x3D = getX3d();
		if((x3D - num * ow)>(ow/2)){//正方向
			num ++;
			if(num == ItemDOM.length){
				num = ItemDOM.length - 1;
			}
			transform3dX(- num * ow);
		}else if((x3D - num * ow)<(-ow/2)){//负方向
			num -- ;
			if(num < 0){
				num = 0;
			}
			transform3dX(- num * ow);
		}else if(Math.abs(x3D - num * ow)<(ow/2)){
			transitionTime(1);
			transform3dX(- num * ow);
		}
		clearDotsClass();
		setDotClass(num);
	}
	idTag.ondragstart = function(){//禁止拖动
		return false;
	}
	
	
	function transitionTime(n){
		GroupDOM.style.transitionDuration = n*timeToLeft + 'ms';
		GroupDOM.style.webkitTransitionDuration = n*timeToLeft + 'ms';
	}
	
	function transform3dX(n){
		var a = 'translate3d(',b = 'px, 0px, 0px) translateZ(0px)';
		GroupDOM.style.transform = a + n + b;
		GroupDOM.style.webkitTransform = a + n + b;
	}
	function getX3d(){
		if(GroupDOM.style.transform){
			return parseInt((GroupDOM.style.transform.match(/\([\S]+,/g) + "").replace(/\-|\(|px|\,/g,""));
			//return parseInt(GroupDOM.style.transform.split(',')[0].split('(')[1].replace(/[^0-9]/g,""));
		}else{
			return parseInt((GroupDOM.style.webkitTransform.match(/\([\S]+,/g) + "").replace(/\-|\(|px|\,/g,""));
			//return parseInt(GroupDOM.style.webkitTransform.split(',')[0].split('(')[1].replace(/[^0-9]/g,""));
		}
	}
	function setDotClass(n){
		if(!obj.isNumShow){
			iDots[n].className = 'active-dots';
		}else{
			sliderDots.getElementsByTagName('span')[0].innerHTML = (n+1) + '/' + (ItemDOM.length-1);
		}
	}
	function clearDotsClass(){
		if(!obj.isNumShow){
			for(var i = 0 ; i < iDots.length ; i ++){
				iDots[i].className = '';
			}
		}
	}
	window.addEventListener('resize', function() {
		//窗口改变事件
		if(ow != idTag.offsetWidth){
			num = 1;
			ow = idTag.offsetWidth;
			oh = ow / obj.ratio;
			idTag.style.height = oh + 'px';
			for(var i = 0; i < aDOM.length; i++) {
				aDOM[i].style.width = ow + 'px';
				aDOM[i].style.height = oh + 'px';
				fitImgSliderMobile(imgDom[i]);
			}
			clearDotsClass();
			setDotClass(0);
			idTag.style.height = oh + 'px';
			transform3dX(- ow);
		}
	}, false);
}

function fitImgSliderMobile(objImg) {
	var liWidth = objImg.parentNode.offsetWidth; //容器li的宽
	var liHeight = objImg.parentNode.offsetHeight; //容器li的高			
	var imgWidth = objImg.width; //图片的宽
	var imgHeight = objImg.height; //图片的高
	var imgScale = ''; //图片缩放倍数

	var liRatio = (liWidth / liHeight); //容器宽高比
	var imgRatio = (imgWidth / imgHeight); //图片宽高比

	if(liRatio >= imgRatio) {
		imgScale = liWidth / imgWidth;
	} else {
		imgScale = liHeight / imgHeight;
	}

	objImg.style.width = (imgWidth * imgScale) + 'px';
	objImg.style.height = (imgHeight * imgScale) + 'px';

	objImg.style.marginLeft = (liWidth - objImg.width) / 2 + 'px';
	objImg.style.marginTop = (liHeight - objImg.height) / 2 + 'px';
} 


sliderProductDetail.min.js使用gulp压缩了sliderProductDetail.js代码

function sliderProductDetail(e){function t(){0!=e.isSlide&&(E=setInterval(function(){if(M++,o(2),l(-M*v),h(),M<g.length-1&&c(M),M==g.length-1){c(0);var e=setTimeout(function(){M=0,o(0),l(0),clearTimeout(e)},2*S+1);P=!1;var t=setTimeout(function(){P=!0,clearTimeout(t)},2*S+1)}},e.time))}function n(){if(clearInterval(E),0!=P){var e=event||window.event;D=e.screenX||e.targetTouches[0].screenX,Y=e.screenY||e.targetTouches[0].screenY,C=new Date,I=!0,B=!0,document.addEventListener("touchmove",i,!1),document.addEventListener("mousemove",i,!1),document.ontouchmove=function(){return!1},clearTimeout(W)}}function i(e){var t=e||window.event;if(X=t.screenX||t.targetTouches[0].screenX,k=t.screenY||t.targetTouches[0].screenY,H=X-D,I&&Math.abs(X-D)-Math.abs(k-Y)>0){B=!1,e.stopPropagation(),e.preventDefault();var n=Math.min(M*v-H,v*(g.length-1));o(0),0==M&&(n=Math.max(n,0)),M==g.length-2&&(n=Math.min(n,v*(g.length-2))),l(-n)}else B&&Math.abs(X-D)-Math.abs(k-Y)<0&&(I=!1,document.ontouchmove=null)}function a(e){clearInterval(E),t(),document.removeEventListener("touchmove",i,!1),document.removeEventListener("mousemove",i,!1),document.ontouchmove=null,F=new Date-C;var e=event||window.event;X=e.screenX||e.changedTouches[0].screenX,k=e.screenY||e.changedTouches[0].screenY,30<F&&F<280&&I?r():F>=280&&s(),D=0,X=0,Y=0,k=0,C=0,F=0,H=0}function r(){H<0&&0!=H?(M++,M==g.length-1&&(M=g.length-2)):H>0&&0!=H&&(M--,M<0&&(M=0)),o(1),l(-M*v),h(),c(M)}function s(){if(0!=P){o(1);var e=m();e-M*v>v/2?(M++,M==g.length&&(M=g.length-1),l(-M*v)):e-M*v<-v/2?(M--,M<0&&(M=0),l(-M*v)):Math.abs(e-M*v)<v/2&&(o(1),l(-M*v)),h(),c(M)}}function o(e){d.style.transitionDuration=e*S+"ms",d.style.webkitTransitionDuration=e*S+"ms"}function l(e){var t="translate3d(",n="px, 0px, 0px) translateZ(0px)";d.style.transform=t+e+n,d.style.webkitTransform=t+e+n}function m(){return d.style.transform?parseInt((d.style.transform.match(/\([\S]+,/g)+"").replace(/\-|\(|px|\,/g,"")):parseInt((d.style.webkitTransform.match(/\([\S]+,/g)+"").replace(/\-|\(|px|\,/g,""))}function c(t){e.isNumShow?x.getElementsByTagName("span")[0].innerHTML=t+1+"/"+(g.length-1):b[t].className="active-dots"}function h(){if(!e.isNumShow)for(var t=0;t<b.length;t++)b[t].className=""}e.time=e.time||1500,e.time=Math.max(e.time,1500),e.ratio=e.ratio||"1:0.58",e.ratio=parseFloat(e.ratio.split(":")[0])/parseFloat(e.ratio.split(":")[1]),e.isSlide=e.isSlide||!1,e.isNumShow=e.isNumShow||!1;var u=document.querySelector(e.id),d=u.getElementsByClassName("slider-group")[0],g=d.getElementsByClassName("slider-item"),f=g[0].cloneNode(!0);d.appendChild(f),u.style.height=p+"px";for(var v=u.offsetWidth,p=v/e.ratio,y=u.getElementsByTagName("a"),T=u.getElementsByTagName("img"),w=0;w<y.length;w++)y[w].style.width=v+"px",y[w].style.height=p+"px",T[w].setAttribute("onload","fitImgSliderMobile(this)"),fitImgSliderMobile(T[w]);var x=document.createElement("div");if(e.isNumShow){x.className="silder-nums";var N="<span>1/"+(g.length-1)+"</span>";x.innerHTML=N,u.appendChild(x)}else{x.className="silder-dots";for(var N="",w=0;w<y.length-1;w++)N+="<i></i>";x.innerHTML=N,u.appendChild(x);var b=x.getElementsByTagName("i")}l(0),c(0);var E,M=0,S=350,L=setTimeout(function(){var e="transform",t="cubic-bezier(0.165, 0.84, 0.44, 1)";d.style.transitionProperty=e,d.style.transitionTimingFunction=t,d.style.webkitTransitionProperty=e,d.style.webkitTransitionTimingFunction=t,o(2),clearTimeout(L)},1);if(2!=y.length){t();var I,B,D=0,X=0,Y=0,k=0,C=0,F=0,H=0,P=!0;u.addEventListener("touchstart",n,!1),u.addEventListener("mousedown",n,!1),document.addEventListener("touchend",a,!1),document.addEventListener("mouseup",a,!1);var W;u.ondragstart=function(){return!1},window.addEventListener("resize",function(){if(v!=u.offsetWidth){M=1,v=u.offsetWidth,p=v/e.ratio,u.style.height=p+"px";for(var t=0;t<y.length;t++)y[t].style.width=v+"px",y[t].style.height=p+"px",fitImgSliderMobile(T[t]);h(),c(0),u.style.height=p+"px",l(-v)}},!1)}}function fitImgSliderMobile(e){var t=e.parentNode.offsetWidth,n=e.parentNode.offsetHeight,i=e.width,a=e.height,r="",s=t/n,o=i/a;r=s>=o?t/i:n/a,e.style.width=i*r+"px",e.style.height=a*r+"px",e.style.marginLeft=(t-e.width)/2+"px",e.style.marginTop=(n-e.height)/2+"px"}

app.css是css重置样式

html {
	font-family: "微软雅黑" "宋体" arial;
}
a, body, center, cite, code, dd, del, div, dl, dt, em, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hr, html, img, input, label, legend, li, mark, ol, p, section, span, strong, textarea, time, ul, var input{
	margin: 0;
	border: 0;
	padding: 0;
	font-style: normal;
	color: #323232;
	box-sizing: border-box;
	-moz-box-sizing:border-box; /* Firefox */
    -webkit-box-sizing:border-box; /* Safari */
}
body, html {
	-webkit-touch-callout: none;
	-webkit-text-size-adjust: none;
	-webkit-tap-highlight-color: transparent;
	-webkit-user-select: none;	
}
article, aside, details, fieldset, figcaption, figure, footer, header, main, nav, section {
	display: block;
}
a, button, cite, code, del, em, img, label, mark, small, strong, textarea, time, var {
	display: inline-block;
}
footer, header, section {
	position: relative;
}
ol, ul {
	list-style: none;
}
button, input, textarea {
	border: 0;
	margin: 0;
	padding: 0;
	font-size: 1em;
	line-height: 1em;
	background-color: transparent;
}
span {
	display: inline-block;
}
a:active, a:hover {
	outline: 0;
}
a, a:visited {
	text-decoration: none;
}
.wordWrap, label {
	word-wrap: break-word;
	word-break: break-all;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
td, th {
	padding: 0;
}
textarea,
input {
     outline: none;
	 border: none;
	-webkit-appearance: none;
	appearance: none;
	border-radius: 0;
}
.clearfix:after {
	content: ' ';
	display: block;
	clear: both;
	visibility: hidden;
	line-height: 0;
	height: 0;
}
.loading_more {
	display: block;
	height: 1.5em;
	width: 100%;
}
.loading_more:before {
	background-image: url(../image/loading_more.gif) 30% center;
	background-repeat: no-repeat;
	background-size: contain;
	text-align: center;
}
.loading_more:after {
	content: '加载更多';
}



支付宝扫码打赏微信打赏

如果文章对您有帮助,不妨移至上方按钮小额赞助我一下,让我有动力继续写出高质量的教程。

发表评论

电子邮件地址不会被公开。