淘宝式轮播图切换太快BUG

Posted 贪吃ღ大魔王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了淘宝式轮播图切换太快BUG相关的知识,希望对你有一定的参考价值。

项目场景:

淘宝式轮播图

问题描述:

手动切换太快,或者设置定时间时间太短,切换都会出现的跳转BUG,

在这里插入图片描述

BUG源码:

JS:

   class swiper {
            constructor() {
                this.ullis = this.$('ul li', true);
                this.ul = this.$('ul');
                this.ol = this.$('ol');
                this.screen = this.$('#screen');
                this.createIndex();
                this.box = this.$('#box');
                this.imgW = this.ullis[0].offsetWidth;
                this.index = 0;
                this.times;
                this.timess;
                this.box.addEventListener('mouseover', this.overFn.bind(this));
                this.box.addEventListener('mouseout', this.outFn.bind(this));
                // 给左右按钮设置点击
                this.$('#left').addEventListener('click', this.leftClick.bind(this));
                this.$('#right').addEventListener('click', this.rightClick.bind(this));
                this.autoplay();
            }
            // 添加序列号
            createIndex() {
                let length = this.ullis.length;
                for (var i = 0; i < length; i++) {
                    let li = document.createElement('li');
                    li.innerhtml = i + 1;
                    i == 0 && (li.className = 'current');
                    this.ol.appendChild(li);
                    li.addEventListener('click', this.olliclick.bind(this));
                }
                this.olli = this.$('ol li', true);
                // 克隆第一张图片
                this.cloneImg();
            }
            cloneImg() {
                let cImg = this.ullis[0].cloneNode(true);
                this.ul.appendChild(cImg);
            }
            // 移入移出 显示左右按钮
            overFn() {
                this.$('#arr').style.display = 'block';
                clearInterval(this.timess);
            }
            outFn() {
                this.$('#arr').style.display = 'none';
                this.autoplay();
            }
            // 左右按钮点击
            leftClick() {
                this.index--;
                if (this.index < 0) {
                    this.ul.style.left = -this.olli.length * this.imgW + 'px';
                    this.index = this.olli.length - 1;
                }
                let target = -this.imgW * this.index;
                this.move(this.ul, { left: target }, function () {
                    console.log('运动了');
                })
                this.olliFn();
            }
            olliclick(eve) {
                this.index = eve.target.innerHTML - 1;
                this.olliFn();
                let target = -this.index * this.imgW;
                this.move(this.ul, { left: target }, function () {

                })
            }
            rightClick() {
                this.index++;
                let target = -this.imgW * this.index;
                let status = false;
                let that = this;
                if (this.index == this.olli.length) {
                    this.index = 0;
                    status = true;
                }
                this.move(this.ul, { left: target }, function () {
                    console.log('运动了');
                    status && (that.ul.style.left = '0px');
                });
                this.olliFn();
            }
            // 序列号的选中
            olliFn() {
                this.$('.current').className = '';
                this.olli[this.index].className = 'current';
            }
            autoplay() {
                this.timess = setInterval(() => {
                    this.rightClick();
                }, 800)
            }

            // 运动函数
            move(tagObj, attrObj, fn) {
                // 防止定时器累加
                clearInterval(this.times);
                // 标识元素到达目标值
                this.times = setInterval(() => {
                    // 遍历素所有的运动属性
                    let onOff = true;
                    for (let attr in attrObj) {
                        // console.log(attr, attrObj[attr]);
                        // 计算speed值
                        let tmpPos = parseInt(this.getPos(tagObj, attr))
                        let speed = (attrObj[attr] - tmpPos) / 10
                        // 对speed取整
                        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                        // console.log(attr, getPos(tagObj, attr));
                        // 到达目标就停止
                        //   if (attrObj[attr] == (tmpPos + speed)) {
                        //     onOff = true;
                        //   }
                        // 设置元素的实时值
                        tagObj.style[attr] = tmpPos + speed + 'px';
                        //console.log(attrObj[attr], tmpPos + speed, speed);
                    }
                    // 判断所有的元素都到达目标值,一个没有到达就设置onoff为false
                    for (let attr in attrObj) {
                        if (attrObj[attr] !== parseInt(this.getPos(tagObj, attr))) {
                            onOff = false
                            break;
                        }
                    }

                    if (onOff) {
                        clearInterval(this.times);
                        // 回调函数目的,将函数内部的值传递出去
                        fn && fn();
                    }

                }, 30)

            }
            $(tag, all = false) {
                return all ? document.querySelectorAll(tag) : document.querySelector(tag);
            }
            // 获取css 样式
            getPos(obj, attr) {
                if (obj.currentStyle) {   // 获取css的样式
                    return obj.currentStyle[attr];
                } else {
                    return getComputedStyle(obj)[attr]
                }
            }
        }
        new swiper;

HTML:

<div class="all" id='box'>
        <div class="screen" id="screen">
            <ul>
                <li>
                    <img src="1.jpg" width="500" height="300" />
                </li>
                <li>
                    <img src="2.jpg" width="500" height="300" />
                </li>
                <li>
                    <img src="3.jpg" width="500" height="300" />
                </li>
                <li>
                    <img src="4.jpg" width="500" height="300" />
                </li>
                <li>
                    <img src="5.jpg" width="500" height="300" />
                </li>
            </ul>
            <ol>

            </ol>
        </div>
        <div id="arr">
            <span id="left">&lt;</span>
            <span id="right">&gt;</span>
        </div>
    </div>

CSS:

   * {
            padding: 0;
            margin: 0;
            list-style: none;
            border: 0;
        }

        .all {
            width: 500px;
            height: 300px;
            padding: 7px;
            border: 1px solid #ccc;
            margin: 100px auto;
            position: relative;
        }

        .screen {
            width: 500px;
            height: 300px;
            overflow: hidden;
            position: relative;
        }

        .screen li {
            width: 500px;
            height: 300px;
            overflow: hidden;
            float: left;
        }

        .screen ul {
            position: absolute;
            left: 0px;
            top: 0px;
            width: 3000px;
        }

        .all ol {
            position: absolute;
            right: 10px;
            bottom: 10px;
            line-height: 20px;
            text-align: center;
        }

        .all ol li {
            float: left;
            width: 20px;
            height: 20px;
            background: #fff;
            border: 1px solid #ccc;
            margin-left: 10px;
            cursor: pointer;
        }

        .all ol li.current {
            background: yellow;
        }

        #arr {
            display: none;
            z-index: 1000;

        }

        #arr span {
            width: 40px;
            height: 40px;
            position: absolute;
            left: 5px;
            top: 50%;
            margin-top: -20px;
            background: #000;
            cursor: pointer;
            line-height: 40px;
            text-align: center;
            font-weight: bold;
            font-family: '黑体';
            font-size: 30px;
            color: #fff;
            opacity: 0.3;
            border: 1px solid #fff;
        }

        #arr #right {
            right: 5px;
            left: auto;
        }

原因分析:

点击左侧按钮切换无问题,点击右侧切换过快,或者定时器设置时间过短,都会导致此现象。


解决方案:

暂无解决,望大佬指出问题。

以上是关于淘宝式轮播图切换太快BUG的主要内容,如果未能解决你的问题,请参考以下文章

H5C3结合JQuery实现的炫酷分裂式轮播图

切换式轮播方式

vue.js实现轮播图

swiper轮播图自动播放速度太快

淘宝首页宽屏图片轮播代码

jQuery轮播图练习