JS实现无限轮播无倒退效果

原理:每次移动前设置transition过渡效果,完成清除过渡效果,然后在到达最后一张图片的时候在清除过渡效果之后translateX(0)

另外需要jq的引用

HTML:

CSS:

.slide-container {
            max-width: 1230px;
            margin: auto;
            overflow: hidden;
        }
        .slide-container li {
            float: left;
        }
        .slide-container img {
            width: 100%;
        }

JS:

第一步我们应该在ul的所有li前面和后面复制一份一摸一样的li数组。

效果图:

                                                                          JS实现无限轮播无倒退效果_第1张图片

 

           JS实现无限轮播无倒退效果_第2张图片

在原来的li集合前后添加了一个一模一样的集合之后,slide-container显示的是prepend(li集合)。

为了使slide-container显示的是最中间的li集合,设置ul:margin-left 和margin-right为负值。大小为一个li集合的宽度。

这样ul实际的宽度就是原来的三倍。slide-container显示的就是最原始的li集合。

let orgLen, canMove, curLi, curLen,
            slider = null,
            interval = null,
            curImgIndex = 0;

        function initSlider() {
            let orgLiArray = document.querySelectorAll('.slide-container li');

            orgLen = orgLiArray.length;
            canMove = true;
            slider = $('.slide-container');

            addLi();
            setStyle();

            //添加li
            function addLi() {
                for (let i = 0; i < orgLen; i++) {
                    let preLi = orgLiArray[orgLen - i - 1].cloneNode(true);
                    let apLi = orgLiArray[i].cloneNode(true);
                    document.querySelector('.slide-container ul').prepend(preLi);
                    document.querySelector('.slide-container ul').append(apLi);
                }
            }

            function setStyle() {
                curLi = slider.find('li');
                curLen = curLi.length;

                curLi.css({
                    'width': 'calc(' + 100 / curLen + '% - 10px)',    //动态设置li的宽度
                    'margin': '0 5px'
                });

                //根据实际li个数与ul中用户能够看到的个数比例设置ul宽度
                slider.find('ul').css({
                    'width': curLen / slider.attr('view-count') * 100 + '%',    
                });

                //获取到设置了width之后的li宽度
                //通过margin-left 与margin-right 为负数 使中间的原始li集合在slide-container显示
                let width = document.defaultView.getComputedStyle(curLi[0]).width.match(/\d*\W\d/g);

                width = (parseFloat(width) + 10) * orgLen;
                slider.find('ul').css({
                    'margin-left': '-' + width + 'px',
                    'margin-right': '-' + width + 'px',
                });
            }
        }        

        /**
         *  移动函数
         *  每次移动后移除过渡效果
         *  当前第一个图片索引值的绝对值大于原始图片数量则恢复为原始状态
         * @param imgIndex
         */
        function move(imgIndex) {
            canMove = false;     //滚轮滚动中不能再次滚动
            clearInterval(interval);    //清除定时器
            slider.find('ul').css({
                'transition': 'all 0.5s linear'
            });

            setTimeout(function () {    //移动
                slider.find('ul').css({
                    'transform': 'translateX( ' + 100 / curLen * -imgIndex + '% )',
                });
                setTimeout(function () {    //移动完成后清除过渡效果
                    slider.find('ul').css({
                        'transition': '',
                    });
                    setTimeout(function () {
                        if (Math.abs(imgIndex) >= orgLen) {    //到达边界回到初始状态
                            curImgIndex = 0;
                            slider.find('ul').css({
                                'transform': 'translateX(0)'
                            });
                        }
                        canMove = true;
                        startInterval();
                    }, 20);
                }, 500);
            }, 20);
        }
        
        function startInterval() {
            interval = setInterval(function () {    //开始轮播
                curImgIndex++;
                move(curImgIndex);
            },2000);
        }

        initSlider();
        startInterval();

然后加入鼠标滚轮实现效果,可以用滚轮切换图片。

先编写具体的处理函数。

//统一处理滚轮滚动事件
        function wheel(event) {
            var delta = 0;
            if (!event) event = window.event;
            if (event.wheelDelta) {     //IE、chrome浏览器使用的是wheelDelta,并且值为“正负120”
                delta = event.wheelDelta / 120;
                if (window.opera)

                //因为IE、chrome等向下滚动是负值,FF是正值,为了处理一致性,在此取反处理
                    delta = -delta;
            } else if (event.detail) {      //FF浏览器使用的是detail,其值为“正负3”
                delta = -event.detail / 3;
            }
            if (delta) {
                handle(delta);

                //阻止事件冒泡和屏幕向下滚动
                event.preventDefault() && event.stopPropagation();
            }

        }

        //上下滚动时的具体处理函数
        function handle(delta) {
            //向上滚动
            if (delta < 0 && canMove) {
                curImgIndex++;
                move(curImgIndex);
            } else if (delta > 0 && canMove) {  //向下滚动
                curImgIndex--;
                move(curImgIndex);
            }
        }

然后绑定滚轮滚动事件

//兼容性写法
        if (window.addEventListener)    //FF,火狐浏览器会识别该方法
            slider.get(0).addEventListener('DOMMouseScroll', wheel, false);
        slider.get(0).onmousewheel = wheel;     //W3C

 

你可能感兴趣的:(Javascript,轮播)