zepto框架以及原生方法实现无缝轮播图

注 :zepto实现在pc端模拟有一定的bug,把里面的start=false注释掉即可

Zepto实现。

HTML代码:

<div class="homePageBanner">
						<ul>
							<li><a href="#"><img src="images/banner4.jpg" alt=""></a></li>
							<li><a href="#"><img src="images/banner1.jpg" alt=""></a></li>
							<li><a href="#"><img src="images/banner2.jpg" alt=""></a></li>
							<li><a href="#"><img src="images/banner3.jpg" alt=""></a></li>
							<li><a href="#"><img src="images/banner4.jpg" alt=""></a></li>
							<li><a href="#"><img src="images/banner1.jpg" alt=""></a></li>
						</ul>
						<ul>
							<li class="active"></li>
							<li></li>
							<li></li>
							<li></li>
						</ul>
					</div>

js代码:(需要引入zepto.js 请到github下载)

$(function(){
	var wd = $('.homePageBanner').width();
    var start = true;
    var timer;
	var $imgList=$('.homePageBanner ul').eq(0);
	var $circle=$('.homePageBanner ul').eq(1);
    $imgList.on('swipeLeft',moveLeft);
    timer=setInterval(moveLeft,2000);
    function moveLeft (){
        // console.log(1);
        if (start) {
            clearInterval(timer);
            start=false;
            var currLeft = parseInt($imgList.position().left);
			$imgList.animate({
                left: currLeft - wd

            }, 500, function () {
                // console.log($imgList.position().left,-5*wd);
               if (parseInt($imgList.position().left)==-5*wd) {
				$imgList.css({
                        left:-wd
                    });
               }
              setIndex();
            })
            timer=setInterval(moveLeft,2000);
        }
    }
    $imgList.on('swipeRight', function () {
        // console.log(2);
        if(start){
            clearInterval(timer);
            start=false;
            var currLeft = parseInt($imgList.position().left);
            $imgList.animate({
                left: currLeft + wd
            }, 500, function () {
               if (parseInt($imgList.position().left)==0) {
				$imgList.css({
                        left:-4*wd
                    });
               }
               setIndex();
            })
            timer=setInterval(moveLeft,2000);
        }
    })
    function setIndex(){
         var i = ($imgList.position().left/-wd)-1;
		 $circle.find('li').eq(i).addClass('active').siblings().removeClass('active');
    }
    $imgList.on('transitionend',function () { 
        start=true;
    })
})

样式部分:(宽度为容器的6倍)

.homePageBanner{
        width: 10rem;
        overflow: hidden;
        //防止影响下方元素
        position: relative;
        margin: 0 auto;
        height: 499/75rem;
        ul:first-child{
            position: absolute;
            width: 600%;
            overflow: hidden;
            left: -100%;
            top: 0;
            height: 499/75rem;
            li{
                width: 16.6667%;
                float: left;
                
                img{
                width: 100%;
                height: 499/75rem;
                display: block;
                }
            }
        }
        
        // 小圆点 
        ul:last-child{
             width: 150/75rem;
            height: 20/75rem;
            position: absolute;
            right: 10/75rem;
            bottom: 20/75rem;
            
            li{
            width: 14.5/75rem;
            height: 14.5/75rem;
            margin-left: 10/75rem;
            border-radius: 50%;
            border: 1px solid #0099cc;
            float: left;
            
            &:first-child{
                margin-left: 0;
                }
            }
            .active{
                background: #0099cc;
                }
            }
    }

原生js实现(可以监控到用户的滑动停留行为)

js代码:

var scrollPic = function(){
	// 获取到外层容器homePageBanner
	var banner = document.getElementsByClassName("homePageBanner")[0];
	// 获取外层容器的宽度,因为每张图片的宽度与容器宽度相同所以这里等同于获取图片的宽度
	var width = banner.offsetWidth;

	//存储图片的容器ul
	var imgBox = banner.getElementsByTagName("ul")[0];

	//存储轮播下方小圆点的容器ul
	var pointBox = banner.getElementsByTagName("ul")[1];

	//获取到所有的小圆点
	var pointList = pointBox.getElementsByTagName("li");
	//定义变量index 用来记录下标 
	var  index = 1;
	// 声明一个变量timer用做定时器名称
	var timer ;
	// 声明一个变量startX用来记录手指触摸时,手指距离屏幕左边的距离
	var startX = 0;
	// 我手指开始触摸时到移动手指这个过程中移动了多少距离
	var moveX = 0;
	// 记录手指移动时,手指距离屏幕左边的距离
	var endX = 0;

	//定义一个过渡函数使得图片在轮播时有过渡效果
	var addTransition = function(){
		imgBox.style.transition = "all .3s ease 0s";
		imgBox.style.webkitTransition = "all .3s ease 0s";
	} 

	//去掉过渡函数
	var removeTransition = function(){
		imgBox.style.transition = "none";
		imgBox.style.webkitTransition = "none";
	} 

	//定义一个移动函数使用transform方法来移动,传入形参t用做需要偏移的位置值
	var setTransform = function(t){
		imgBox.style.transform = "translate("+t+"px)";
		imgBox.style.webkitTransform = "translate("+t+"px)";
	} 

	//定义小圆点函数动态添加active类,原理:先清空所有样式再给指定的小圆点添加active类,传入的形参n用做小标,因为复制了首尾两张图片所有这里n-1
	var setpoint = function(n){
		for (var i = 0; i < pointList.length; i++) {
			pointList[i].className = '';
		};
		// 如果到了第六张图片让他变成第二张。注:复制了首尾两张图片所以第一张要显示的图片是下标1
		if (n >= 5) {
			n = 1;
		}else if(n <= 0){
			n = 4;
		}
		pointList[n-1].className ='active';
	}

	

	//定时函数,每次让下标++,调用过渡函数,调用偏移函数,传入的值为-index*width因为是向左偏移所以这里index是负值,width是图片的宽度,每次移动一个-index*width的距离
	timer = setInterval(function(){
		index++;
		addTransition();
		setTransform(-index*width);
		// 把当前下标闯入设置小圆点类的函数,使得小圆点根据index值动态添加active类
		 setpoint(index);

	}, 3000)

	//监听动画结束后的函数

	imgBox.addEventListener('transitionEnd', function(){
		// 做出判断,如果到了最后一张克隆的a图片就让他的下标成为真正的下标为1的a图片
		if (index >= 5) {
			index = 1;
		// 做出判断,如果到了第一张下标为0的克隆的d图片就让他的下标成为真正的下标为4的d图片
		}else if(index <= 0){
			index = 4;
		}
		// 移除动画效果,这一步使得无缝轮播视觉效果看不出来
		removeTransition();
		// 调用偏移函数,传入的值为-index*width因为是向左偏移所以这里index是负值,width是图片的宽度,每次移动一个-index*width的距离
		setTransform(-index*width);

	},false)
	// 以上兼容写法
	imgBox.addEventListener('webkitTransitionEnd', function(){
		if (index >= 5) {
			index = 1;
		}else if(index <= 0){
			index = 4;
		}

		removeTransition();
		setTransform(-index*width);

	},false)



//触摸事件开始,当手指开始触摸时的函数
	imgBox.addEventListener('touchstart', function(e){
		//console.log('strat');
		// 记录开始的位置,获取到手指触摸时手指距离屏幕左边的距离
		startX = e.touches[0].clientX;
	})

	//触摸滑动事件开始,手指移动时的事件
	imgBox.addEventListener('touchmove', function(e){
		//清除定时器
		clearInterval(timer);
		// 清除默认的滚动事件
		e.preventDefault();
		// 记录手指移动时,手指距离屏幕左边的距离
		endX = e.touches[0].clientX;
		//记录手指在触摸时并且移动的过程中产生的这个距离startX - endX,用刚触碰时获取到的距离减去我触摸移动时手指距离屏幕左边距离,
		// 得到我手指开始触摸时到移动手指这个过程中移动了多少距离
		moveX = startX - endX;
		// 移除动画函数使得移动过程中图片跟着手指移动
		removeTransition();
		// 设置移动过程中图片跟着手指移动的距离
		setTransform(-index * width - moveX)
	})

	//触摸滑动事件结束
	imgBox.addEventListener('touchend', function(e){
		//如果移动的距离大于三分之一时向左滑,否则向右滑
		if( Math.abs(moveX) > (1/3*width) && endX != 0){
			// 向左
			if (moveX > 0) {
				index++;
			}else{
				index--;
			}
			// 改变位置
			setTransform(-index*width);
			setpoint(index);

		}

		// 手指松开时图片回到原来的位置
		addTransition();
		setTransform(-index*width);

		startX = 0;
		endX = 0;
		// 清空上一次定时器
		clearInterval(timer);

		//重新调用定时器
		timer = setInterval(function(){
			index++;
			addTransition();
			setTransform(-index*width);
			setpoint(index);
		}, 3000)

	})

}

//banner 调用方法
scrollPic();

注:HTML布局保持一致,css部分采用的是transform:translateX的方式,把定位属性改为translate即可,初始值是-16.66667%负一张图片的宽度,因为在最前面放的是克隆的第四张图片。
本博客内容均为原创,转载请加以说明。

猜你喜欢

转载自blog.csdn.net/isMrcat/article/details/84233882