无缝轮播图

 html组件:

<div class="carousel-wrap" needCarousel needAutoCarousel >

<!--

自定义属性:

needCarousel:是否需要无缝轮播

needAutoCarousel:是否需要自动轮播

-->
       <div class="points-wrap"></div>
</div>

 

JS轮播组件:

function(arr){

//参数arr代表需要轮播图片的数组
        var carousel = document.querySelector(".carousel-wrap");
        var pointsArr = arr;
        //是否需要无缝滑屏
        var needCarousel = carousel.getAttribute("needCarousel");
        needCarousel=needCarousel!=null?true:false;

        //如果需要无缝轮播则需要拷贝图片数组
        if(needCarousel){
            arr = arr.concat(arr);
        }
        
        if(carousel){
            //轮播图片列表布局
            var ulNode = document.createElement("ul");
            var styleNode = document.createElement("style");
            ulNode.classList.add("list");
            for(var i = 0 ;i<arr.length;i++){
                ulNode.innerHTML+='<li><a href=""><img src="'+arr[i]+'" alt="" /></a></li>'
            }
            styleNode.innerHTML=".carousel-wrap>.list{width: "+arr.length*100+"%;}.carousel-wrap>.list li{width: "+(1/arr.length*100)+"%;}"
            carousel.appendChild(ulNode);
            document.head.appendChild(styleNode);
           
            var imgNode = document.querySelector(".carousel-wrap>.list a>img");

//需要延迟一段时间好让浏览器先渲染完DOM结构
            setInterval(function(){
                carousel.style.height = imgNode.offsetHeight+"px";
            },100);
            
            var pointsWrap = document.querySelector(".carousel-wrap > .points-wrap");
            if(pointsWrap){
                for(var i = 0 ;i<pointsArr.length;i++){
                    if(i==0){
                        pointsWrap.innerHTML+="<span class='active'></span>";
                    }else{
                        pointsWrap.innerHTML+="<span></span>";
                    }
                }
                var pointsSpan = document.querySelectorAll(".carousel-wrap > .points-wrap > span");
            }
            /*
             滑屏
                1,拿到元素一开始位置
                2,拿到手指一开始的位置
                3,拿到手指move的实时位置
                4,将手指移动的距离加给元素
            */
            var index=0;
            //X轴上:手指、元素一开始的位置
            var startX=0;
            var elementX=0;
            
            //Y轴上:手指、元素一开始的位置
            var startY=0;
            var elementY=0;


            //是否是X轴滑屏,主要用来防控抖动
            var isX=true;

            //是否是第一次滑动
            var isFrist=true;
            carousel.addEventListener("touchstart",function(ev){
                ev = ev || event;
                var TouchC = ev.changedTouches[0];
                ulNode.style.transition="none";
                /*
                无缝滑屏
                    1,点击第一组的第一张时,瞬间跳到第二组的第一张
                    2,点击最后一组的最后一张时,瞬间跳到第一组的最后一张
                */
                if(needCarousel){

                    //获取轮播图片的索引
                    var index = tai.transformCss(ulNode,"translateX")/document.documentElement.clientWidth;
                    if(index==0){

                        //如果是第一张图片,那么则跳转到第二组图片的第一张
                        index = -pointsArr.length;
                    }else if(-index==arr.length-1){

                        //如果是最后一张图片,那么则跳转到第一组图片的最后一张
                        index = 1-pointsArr.length;
                    }

                    //设置移动位置
                    tai.transformCss(ulNode,"translateX",index*document.documentElement.clientWidth);
                }
                
                startX = TouchC.clientX;
                elementX = tai.transformCss(ulNode,"translateX");
                
                startY = TouchC.clientY;
                elementY = tai.transformCss(ulNode,"translateY");
                clearInterval(carouselTimer);
                isX=true;
                isFrist=true;
            });
            carousel.addEventListener("touchmove",function(ev){
                //判断"第一次之后"的滑动效果
                if(!isX){
                    return;
                }
                ev = ev || event;
                var TouchC = ev.changedTouches[0];
                var moveX = TouchC.clientX;
                var disX = moveX - startX;
                var moveY = TouchC.clientY;
                var disY = moveY-startY;
                /*
                 * 防抖动:
                 * 如果手指一开始在X轴上滑动,那么之后无论怎么滑,都会抖动
                 * 如果手指一开始在Y轴上滑动,那么之后无论怎么滑,都不会抖动
                 * 
                 * */
                //判断第一次滑动的方向,并确定是否禁掉之后滑动效果
                if(isFrist){
                    isFrist=false;
                    //判断用户滑动的方向,如果y>x,那么代表第一次滑动的是y轴
                    if(Math.abs(disY)>Math.abs(disX)){
                        isX=false;
                        return ;
                    }
                }
                //设置滑屏位置:滑屏位置应该=上次滑屏位置+当前移动的位置
                tai.transformCss(ulNode,"translateX",elementX + disX);
            });
            carousel.addEventListener("touchend",function(ev){
                ev = ev || event;

                //获取当前图片索引
                index = tai.transformCss(ulNode,"translateX")/document.documentElement.clientWidth;
                index = Math.round(index);

                //如果第一张向右滑动,那么索引为第一张图片
                if(index > 0){
                    index=0;

                //如果最后一张向左滑动,那么索引为最后一张图片
                }else if(index<1-arr.length){
                    index=1-arr.length;
                }
                pointActive(index)
                ulNode.style.transition = ".5s transform";
                
                translateX = index*document.documentElement.clientWidth;
                tai.transformCss(ulNode,"translateX",translateX);

                //手动滑屏之后,判断是否开启了自动滑屏
                if(needAutoCarousel){
                    autoCarousel();
                }
            });
            
            //自动轮播
            var carouselTimer=0;
            var needAutoCarousel = carousel.getAttribute("needAutoCarousel");
            needAutoCarousel = needAutoCarousel!=null?true:false;
            if(needAutoCarousel){
                autoCarousel();
            }
            function autoCarousel(){
                clearInterval(carouselTimer);
                carouselTimer = setInterval(function(){

                    //自动轮播时,如果轮播到最后一张时,那么将回到第一组的最后一张,并设置起过渡效果为none
                    if(index==1-arr.length){
                        index=1-arr.length/2;
                        ulNode.style.transition="none";
                        tai.transformCss(ulNode,"translateX",index*document.documentElement.clientWidth);
                    }
                    setTimeout(function(){
                        index--;
                        pointActive(index);
                        ulNode.style.transition=".5s transform";
                        tai.transformCss(ulNode,"translateX",index*document.documentElement.clientWidth);
                    },50);
                    
                },2000);
            }
            
            //圆点样式
            function pointActive(index){
                if(!pointsWrap){
                    return;
                }
                for(var i=0;i<pointsSpan.length;i++){
                    pointsSpan[i].classList.remove("active");
                }
                pointsSpan[-index%pointsArr.length].classList.add("active");
            }
        }
    }

 

注:其中tai.transformCss(v1,v2,v3)函数请参考https://blog.csdn.net/qq_35165469/article/details/91050052链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值