JS原生无缝轮播防抖
前言
在19年的时候发了一篇原生JS轮播的博文有80+的收藏量,思路没有问题,但是代码值得优化,所以今天重新再用原生JS来写一下轮播,毕竟经典的案例永远是经典的案例。要查看原理和具体效果的移步之前的博文,JS原生轮播图。
结构
首先搭建html结构,值得注意的有以下几点
- 包裹轮播图的盒子应该分为3层,最里面的一层应该为包含一张轮播图的div,中间一层为包含所有轮播图的div,最外一层则包裹中间的盒子。最外面一层再和箭头盒子,下方小圆点盒子互为兄弟关系一同放在一个大的div中。
- 如果为无缝轮播,5张图则按照5123451的顺序放置。
- 轮播大盒子与箭头盒子和下方小圆点盒子为兄弟关系。
代码如下:
<div class="wufeng">
<div class="wfimgs" id="wfimgs">
<div class="wfbox" id="wfbox">
<div>
<img src="./lunbo/5.jpg" alt="">
</div>
<div>
<img src="./lunbo/1.jpg" alt="">
</div>
<div>
<img src="./lunbo/2.jpg" alt="">
</div>
<div>
<img src="./lunbo/3.jpg" alt="">
</div>
<div>
<img src="./lunbo/6.jpg" alt="">
</div>
<div>
<img src="./lunbo/5.jpg" alt="">
</div>
<div>
<img src="./lunbo/1.jpg" alt="">
</div>
</div>
</div>
<div class="wfjiantou">
<div class="left" id="left"><</div>
<div class="right" id="right">></div>
</div>
<ul>
<li data-id="1" onclick="wfli(this)"></li>
<li data-id="2" onclick="wfli(this)"></li>
<li data-id="3" onclick="wfli(this)"></li>
<li data-id="4" onclick="wfli(this)"></li>
<li data-id="5" onclick="wfli(this)"></li>
</ul>
</div>
样式
样式主要注意在轮播图的设计上:
设置轮播图盒子为1000px宽,全部左浮动,则中间的盒子为7000px宽,清除浮动,外层盒子为1000px宽并设置溢出隐藏。中间盒子设置为绝对定位,外层盒子为相对定位。,因为每次移动的是中间的盒子,每向右走一张图,中间的盒子偏移多-1000px。
完整样式代码:
*{
margin: 0;
padding: 0;
}
.wufeng{
position: relative;
}
.wfimgs{
width: 1000px;
position: relative;
/* overflow: hidden; */
height: 250px;
margin: 0 auto;
}
.wfimgs:hover+.wfjiantou{
opacity: 1;
}
.wfbox{
width: 7000px;
overflow: hidden;
position: absolute;
transition: all 1s;
}
.wfbox div{
float: left;
width: 1000px;
}
.wfbox img{
width: 100%;
}
.wfjiantou{
opacity: 0;
position: absolute;
width: 1000px;
top: 25%;
left: 17.5%;
transition: all 0.3s;
}
.wfjiantou:hover{
opacity: 1;
}
.wfjiantou div{
transition: all 0.3s;
width: 50px;
height: 50px;
line-height: 50px;
text-align: center;
font-size: larger;
border-radius: 50%;
color: rgb(208, 208, 208);
border: 1px solid rgb(221, 221, 221);
}
.wfjiantou div:hover{
background-color: rgba(233, 233, 233, 0.347);
color: white;
}
.left{
float: left;
}
.right{
float: right;
}
ul{
overflow: hidden;
position: absolute;
top: 80%;
left: 48%;
width: 100px;
}
ul li{
float: left;
width: 10px;
height: 10px;
border-radius: 50%;
border: 1px solid white;
margin: 0 4%;
list-style: none;
}
控制
自动轮播
实现自动轮播,首先让盒子初始偏移量为-1000px保证当前为1.jpg,而不是开头的5.jpg。
加定时器,设置盒子每2s偏移量加-1000,动画效果设置为1s,同时清除上一个小圆点样式,并给当前小圆点加样式。
注意判断边界值(核心),当到达后面的1.jpg(23451)时候,为了做出无缝效果,开启定时器setTimeout,设值时间为900ms,即900ms后,清除动画效果跳到开头的1.jpg(51234),重置盒子偏移量为-1000px。
let wfbox = document.getElementById('wfbox')
let left = document.getElementById('left')
let right = document.getElementById('right')
let ul = document.getElementsByTagName('ul')[0]
wfbox.style.left = '-1000px'
let i = 0
ul.children[0].style.backgroundColor = 'red'
let mleft = -1000
let automove
wfauto()
function wfauto(){
automove = setInterval(function(){
wfbox.style.transition = 'all 1s'
mleft = mleft-1000
wfbox.style.left = `${mleft}px`
i = i+1
if(i == 5){
ul.children[4].style.backgroundColor = ''
i = 0
ul.children[0].style.backgroundColor = 'red'
}else{
ul.children[i].style.backgroundColor = 'red'
ul.children[i-1].style.backgroundColor = ''
}
if(mleft == -6000){
let timer
clearTimeout(timer)
timer = setTimeout(function(){
wfbox.style.transition = 'all 0s'
mleft = -1000
wfbox.style.left = `${mleft}px`
},900)
}
},2000)
}
控制自动轮播的暂停和继续
right.onmouseover = () =>{
clearInterval(automove)
}
left.onmouseover = () =>{
clearInterval(automove)
}
right.onmouseleave = () =>{
wfauto()
}
left.onmouseleave = () =>{
wfauto()
}
wfimgs.onmouseenter=()=>{
clearInterval(automove)
}
wfimgs.onmouseleave=()=>{
wfauto()
}
控制左右点击
right.onclick = () =>{
wfbox.style.transition = 'all 1s'
mleft = mleft-1000
wfbox.style.left = `${mleft}px`
i = i+1
if(i == 5){
ul.children[4].style.backgroundColor = ''
i = 0
ul.children[0].style.backgroundColor = 'red'
}else{
ul.children[i].style.backgroundColor = 'red'
ul.children[i-1].style.backgroundColor = ''
}
if(mleft == -6000){
let timer
clearTimeout(timer)
timer = setTimeout(function(){
wfbox.style.transition = 'all 0s'
mleft = -1000
wfbox.style.left = `${mleft}px`
},900)
}
}
left.onclick = () =>{
wfbox.style.transition = 'all 1s'
mleft = mleft+1000
wfbox.style.left = `${mleft}px`
i = i-1
if(i == -1){
ul.children[0].style.backgroundColor = ''
i = 4
ul.children[4].style.backgroundColor = 'red'
}else{
ul.children[i].style.backgroundColor = 'red'
ul.children[i+1].style.backgroundColor = ''
}
if(mleft == 0){
let timer
clearTimeout(timer)
timer = setTimeout(function(){
wfbox.style.transition = 'all 0s'
mleft = -5000
wfbox.style.left = `${mleft}px`
},900)
}
}
控制小圆点的点击切换
const wfli = (obj) =>{
clearInterval(automove)
console.log(obj.dataset.id)
mleft = -1000*obj.dataset.id
wfbox.style.left = `${mleft}px`
for(let i = 0;i<5;i++){
ul.children[i].style.backgroundColor = ''
}
i = obj.dataset.id-1
ul.children[i].style.backgroundColor = 'red'
wfauto()
}