轮播图功能分析:
- 可以自动循环
- 点击轮播图下面的上一页下一页按钮,轮播图也可以进行播放
- 当鼠标放在轮播图上时,停止播放,当鼠标离开时,则继续播放
它涉及到了两个定时器: 第一个定时器是用更换图片的,第二个定时器用来每隔15ms往前移动图片10px。这两点我在看这个原理的时候,超级惊讶,就没想到一个轮播图往前移动也会有一个定时器来播放它。大家可以猜一下,定时器有setTimeOut和setInterval两个定时器,应该用哪个?两个定时器都要用到setInterval,不停的播放!
<div id="box">
<ul class="pic_list">
<li class="item"><img class="pic" src="img/img2.jpg" alt="">li>
<li class="item"><img class="pic" src="img/img3.jpg" alt="">li>
<li class="item"><img class="pic" src="img/img4.jpg" alt="">li>
ul>
div>
<div class="btn">
<button id="prev">前一张button>
<button id="next">后一张button>
div>
设定轮播三张图片:
#box {
width: 400px;
height: 300px;
position: relative;
margin: 0 auto;
overflow: hidden;
}
.pic_list {
list-style: none;
width: 500%;
height: 300px;
position: relative;
padding: 0;
margin: 0;
top: 0px;
}
.pic {
width: 400px;
height: 300px;
padding: 0;
margin: 0;
}
.item {
float: left;
}
.btn {
margin: 10px auto;
width: 150px;
}
1. 初始化:
获取pic_list,用于通过style上的left改变位置,点击下一张的话,向左移动,点击上一张,则向右移动。
let imags = document.querySelector('.pic_list');//同样移动图片
获取轮播图有几张图片
let length = document.querySelectorAll('.item').length;//减去在头和尾部加的两张图片
初始化列表最开始的位置
imags.style.left = '0' + 'px';//初始化列表最开始的位置
这是一些参数,time
是第一个定时器(用于跳到下一张,每隔2400ms便跳转到下一张)。time2
第二个定时器(图片每隔15ms便向左移动10px)。distance
记录图片一共移动的距离。index
记录图片当前的索引
let time = null, time2 = null, distance = 0, index = 1;
2. init函数,轮播图中的一些鼠标事件都会在这里定义。
const box = document.querySelector('#box');
const pre = document.querySelector('#prev');
const next = document.querySelector('#next');
pre.onclick = function () {
animate(1);
}
next.onclick = function () {
animate(2);
}
box.addEventListener('onmouseenter', function () {
clearInterval(time);//鼠标进入清除定时器
}, 2500);
box.addEventListener('onmouseleave', function () {
// 鼠标离开开启定时器
time = setInterval(function () {
// clearInterval(time2)
animate(2);
}, 2500)
})
3. 动画函数
imags.style.left = (parseInt(imags.style.left) + step) + 'px'
function animate(num) {
console.log(time2)
if (!time2) {
time2 = setInterval(function () {
let step = num === 1 ? 10 : -10;
distance += Math.abs(step);
imags.style.left = (parseInt(imags.style.left) + step) + 'px'
if (distance >= 400) {
clearInterval(time2)//重新计时
time2 = null;
distance = 0;//重新计算距离
if (step > 0) index -= 1;//点击pre,index图片列表就-1
if (step < 0) index += 1;//点击next,index图片列表就+1
if (index > length) {//已经滑到图片列表的尾部
index = 1;
imags.style.left = 0 + 'px';
} else if (index < 1) {
index = length;
imags.style.left = (-400) * (length - 1) + 'px';
}
console.log(index)
}
}, 15)
}
}
这样写其实有点bug:
小bug
这里回到页面样式这部分,一开始我很不理解为什么要在头和尾处添加两张重复的图片,为什么要添加?作用是啥呢?后来我就把他删了,也能实现出来。但是出现了这样的bug,这时候才明白添加这两张图片是很有必要的。比如说当图片运行到最后一张的时候,此时index=3,还会再继续往前进,但是前面是空白,当移动400px的时候,此时index=4,才会进入临界条件,imags的位置重新赋值,移动到第一个图片但是这段时间的空白怎么办?确实可以从最后一个移动到第一个,但是在移动的过程中会有空白出现,此时在图片列表左右添加上两张图片就不会出现这种情况了,下面的代码,完美的解决了这个问题:
//这一块记得修改哈
let length = document.querySelectorAll('.item').length - 2;
imags.style.left = '-400' + 'px';//初始化列表最开始的位置
function animate(num) {
if (!time2) {
time2 = setInterval(function () {
let step = num === 1 ? 10 : -10;
distance += Math.abs(step);
imags.style.left = (parseInt(imags.style.left) + step) + 'px'
if (distance >= 400) {
clearInterval(time2)//重新计时
time2 = null;
distance = 0;//重新计算距离
if (step > 0) index -= 1;//点击pre,index图片列表就-1
if (step < 0) index += 1;//点击next,index图片列表就+1
if (index > length) {//已经滑到图片列表的尾部
index = 1;
imags.style.left = -400 + 'px';
} else if (index < 1) {
index = length;
imags.style.left = (-400) * length + 'px';
}
console.log(index)
}
}, 15)
}
}