淘宝式轮播图切换太快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"><</span>
<span id="right">></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的主要内容,如果未能解决你的问题,请参考以下文章