脚本宝典收集整理的这篇文章主要介绍了用状态机写轮播,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
刚刚的轮播用具体思维做,因为不知道它有哪几种状态,就一步步来做,等效果做出来后,哪几种状态,一目了然。下面就用抽象思维做一遍.
用抽象思维做
初始化CSS样式
*{
margin:0;
padding:0;
box-sizing:border-box;
}
.window{
width:400px;
height:300px;
overflow:hidden;
margin:20px auto
}
.images{
position:relative;
}
.images > img{
position:absolute;
transition:all 0.5s;
width:100%;
top:0;
}
轮播状态
先来看下这个轮播有那几种状态
- 图片出现在视窗状态,我用 current 表示
- 图片离开视窗状态,我用 leave 表示
- 图片准备进入视窗状态,我用 enter 表示
现在就是要写三个类,通过JS 激活class 来实现轮播
.images > img.current{
transform:translateX(0);
z-index:1;
}
.images > img.leave{
transform:translateX(-100%);
z-index:1;
}
.images > img.enter{
transform:translateX(100%);
}
梳理下每张图片的状态
- 初始化每张图片的位置,图片1 出现在当前视窗
current
,图片2、图片3 应该在视窗右边待命,随时准备进入视窗enter
- 当图片1 离开视窗时
leave
,图片2 进入视窗current
- 当上一步全部完成后,图片1 应该进入右边待命,等待着进入视窗
- 这里主要绝对定位后,会触发Bfc
$('#images > img:nth-child(1)').addClass('current');
$('#images > img:nth-child(2)').addClass('enter');
$('#images > img:nth-child(3)').addClass('enter');
setTimeout(function(){
$('#images > img:nth-child(1)').removeClass('current').addClass('leave').one('transitionend',function(e){
$(e.currentTarget).addClass('enter').removeClass('leave')
});
$('#images > img:nth-child(2)').removeClass('enter').addClass('current')
},3000);
setTimeout(function(){
$('#images > img:nth-child(2)').removeClass('current').addClass('leave').one('transitionend',function(e){
$(e.currentTarget).addClass('enter').removeClass('leave')
});
$('#images > img:nth-child(3)').removeClass('enter').addClass('current')
},6000);
setTimeout(function(){
$('#images > img:nth-child(3)').removeClass('current').addClass('leave').one('transitionend',function(e){
$(e.currentTarget).addClass('enter').removeClass('leave')
});
$('#images > img:nth-child(1)').removeClass('enter').addClass('current')
},9000);
这样一轮循环就结束了,可以在往后添加setTimeout
方法。
无限循环下去
大量重复的代码就需要寻找合适的的API 代替,一直播下去我们可以使用DOM APIsetInterval()
$('#images > img:nth-child(1)').addClass('current');
$('#images > img:nth-child(2)').addClass('enter');
$('#images > img:nth-child(3)').addClass('enter');
let n = 1;
setInterval(function(){
$(`#images > img:nth-child(${x(n)})`).removeClass('current').addClass('leave').one('transitionend',function(e){
$(e.currentTarget).addClass('enter').removeClass('leave')
});
$(`#images > img:nth-child(${x(n+1)})`).removeClass('enter').addClass('current')
n++; //这里n 是自然增长,让它一直玄幻下去
},3000)
//n取值应该是[1,2,3,4,5,...,size]
let allImages = $('#images > img');
let size = allImages.length;
function x(n){
if(n > size){ //如果n 大于节点size,n就取余
n = n%size;
if(n === 0){ //如果n 取余为0,则让n等于size
n = size;
}
}
return n;
}
这样就是实现了无缝轮播,上面用到了ES6的插值法。
在CSS中img:nth-child(n)
是没有这种写法的,它不能像JS一样可以用变量,这边就用到了ES6 的插值法
`img:nth-child(${n})`
最后优化下刚刚写的代码