因为我个人被无缝轮播折磨了许久,所以写出来分享一下,感觉现在的思路还算清晰。
思路:
无缝轮播实际上就是在我们所有的图片后面增加了一张假的第一张图片。
这样当最后一张切换到第一张的时候,看似好像是直接无缝的,实际上你看到的是一张假的第一张图片,然后又瞬间从假的图片切换回第一张真实的图片。
注意:也要注意动画效果之间的切换!!!
话不多说,还是直接看代码吧。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
* {
margin: 0;
padding: 0;
list-style-type: none;
box-sizing: border-box;
}
.wrap {
position: relative;
width: 900px;
height: 500px;
margin: 100px auto;
overflow: hidden;
}
.wrap .image_box {
position: absolute;
width: 5400px;
height: 500px;
left: 0;
transition: 0.5s ease;
}
.image_box img {
width: 900px;
height: 500px;
display: block;
float: left;
}
.btn {
position: absolute;
width: 100%;
height: 50px;
top: 0;
bottom: 0;
margin: auto;
}
.btn a {
position: absolute;
display: block;
width: 50px;
height: 50px;
background-color: #fff;
opacity: 0.8;
text-decoration: none;
text-align: center;
line-height: 50px;
font-size: 20px;
}
.btn a:nth-child(2) {
right: 0;
}
.circles {
position: absolute;
width: 200px;
height: 20px;
border-radius: 20px;
right: 0;
left: 0;
bottom: 10px;
margin: 0 auto;
display: flex;
justify-content: space-evenly;
}
.circles li {
float: left;
display: block;
height: 20px;
width: 20px;
border-radius: 50%;
background-color: orange;
}
.a {
opacity: 0.5;
}
</style>
<body>
<!-- 显示图片的盒子 -->
<div class="wrap">
<!-- 轮播图片列表 -->
<div class="image_box">
<img src="./imgs/轮播1.jpg" alt="">
<img src="./imgs/轮播2.png" alt="">
<img src="./imgs/轮播3.jpg" alt="">
<img src="./imgs/轮播4.jpg" alt="">
<img src="./imgs/轮播5.jpeg" alt="">
</div>
<!-- 左右按钮 -->
<div class="btn">
<a href="javascript:;" class="left_btn"><</a>
<a href="javascript:;" class="right_btn">></a>
</div>
<!-- 小圆点 -->
<ul class="circles">
<li class="a"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</body>
<script>
//获取图片列表
var imgs = document.querySelector('.image_box');
//获取左右点击按钮
var left_btn = document.querySelector('.left_btn');
var right_btn = document.querySelector('.right_btn');
//获取小圆点
var circles = document.querySelectorAll('.circles li')
//定义一个变量代表索引,注意索引值跟图片的索引是一一对应的,索引值=图片的个数-1
var index = 0;
//设置节流
//所谓节流就是说 只有当图片完全切换过去之后你的点击才会生效
var lock = true;
//如果想要无缝轮播的话,我们需要在最后一张图片后面追加一张假的第一张图片,以此来实现好像图片是连在一起的效果
//克隆第一张图片追加在最后一张图片后
var first_img = imgs.firstElementChild.cloneNode();
imgs.appendChild(first_img);
//右按钮点击事件
right_btn.addEventListener('click', function () {
//!lock 等价于 lock===false
//只有一行的话可以省略{}
if (!lock) return;
index++;
imgs.style.left = index * -900 + 'px';
//需要重新加上动画效果
imgs.style.transition = '0.5s ease'
//当图片位移到最后一张假图片时,需要它先执行过渡效果然后马上取消过渡效果回到第一张真图片
if (index === 5) {
index = 0;
setTimeout(function () {
imgs.style.left = 0;
//此时取消了过渡效果,那么之后所有的过渡效果都会取消
imgs.style.transition = 'none';
// 这里的500毫秒延迟是因为渐变的效果时500毫秒,等动画执行完之后直接跳转到第一张图片
}, 500)
}
setCircles()
//当上面代码执行完后,关锁
lock = false;
//这里的500毫秒是因为动画效果是500ms,图片必须要动画完成过渡后才会开锁,点击事件才会生效
setTimeout(function () {
lock = true
}, 500)
})
//左按钮点击事件
left_btn.addEventListener('click', function () {
if (!lock) return;
index--;
if (index === -1) {
index = 4;
//当索引为-1时,马上跳转到最后一张假图片(此时不应该有过渡效果,不然就会被看出来)
imgs.style.left = 5 * -900 + 'px';
//取消过渡效果
imgs.style.transition = 'none';
//这里的延时没有写时间,就是尽快执行的意思
setTimeout(function () {
imgs.style.left = index * -900 + 'px';
//上面取消了,后面就要再加上过渡效果
imgs.style.transition = '0.5s ease';
})
} else {
//如果索引不为-1时,就是正常的位移
imgs.style.left = index * -900 + 'px';
}
setCircles()
lock = false;
setTimeout(function () {
lock = true;
}, 500)
})
//小圆点改变颜色
function setCircles() {
for (var i = 0; i < circles.length; i++) {
if (index === i) {
//这里是给小圆点添加一个类,样式都写在了这个名字为a的类里
circles[i].classList.add('a')
} else {
circles[i].classList.remove('a')
}
}
}
</script>
</html>