博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用状态机写轮播
阅读量:7091 次
发布时间:2019-06-28

本文共 3430 字,大约阅读时间需要 11 分钟。

刚刚的轮播用具体思维做,因为不知道它有哪几种状态,就一步步来做,等效果做出来后,哪几种状态,一目了然。下面就用抽象思维做一遍.

用抽象思维做

初始化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;}

轮播状态

先来看下这个轮播有那几种状态

  1. 图片出现在视窗状态,我用 current 表示
  2. 图片离开视窗状态,我用 leave 表示
  3. 图片准备进入视窗状态,我用 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. 初始化每张图片的位置,图片1 出现在当前视窗current,图片2、图片3 应该在视窗右边待命,随时准备进入视窗enter
  2. 当图片1 离开视窗时leave,图片2 进入视窗current
  3. 当上一步全部完成后,图片1 应该进入右边待命,等待着进入视窗
  4. 这里主要绝对定位后,会触发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})`\

最后优化下刚刚写的代码

优化完了之后,实际代码就只有这么多,这个被称为状态机,现在再看轮播后,脑海里已经自动变成了状态机了。

let n = 1;int();setInterval(function(){    makeLeave(getImage(n)).one('transitionend',function(e){        makeEnter($(e.currentTarget))    });    makeCurrent(getImage(n+1));    n++;    //这里n 是自然增长,让它一直循环下去},1000);

这里我遇到一个最大的问题之前,是用setTimeout()方法写的代码,后面做无限循环时没想到用setInterval()方法,怎么调试都不对,这里看下它们两个的区别:

setTimeout()方法设置一个定时器,在到时间后执行一段代码或者函数
setInterval()方法是重复调用一段代码或者函数,每次调用之间有固定的时间延时
我们上面写在setInterval()方法内的函数其实就是一段固定的代码,每个一段时间执行一次,就变成我们看到的轮播了

总结

这一篇的核心是状态机,把动作变成一个个状态。用具体化写出的代码都是执行的动作,而用抽象化写出的代码都是完成后的状态,代码结构更清晰,更美观。当然要能写抽象化的代码,肯定少不了具体化的思维。

用这种方法最大的好处是行为样式分离,如果我要给变轮播的方向,只需要改变CSS中的移动方向即可,还可以根据需要加上一些酷炫的操作。

转载地址:http://ptiql.baihongyu.com/

你可能感兴趣的文章
【CentOS 7笔记47】,rsync文件同步工具#171205
查看>>
gitlab ssh key
查看>>
Tomcat 不同端口配置两个应用程序
查看>>
我的友情链接
查看>>
asp.net 插入视频
查看>>
11、网络--Linux Bridge(网桥基础)
查看>>
参观迅达云成观后感
查看>>
一八年第三天晚上十点半的thinking
查看>>
swift 实践- 11 -- UISlider
查看>>
DirectX11 SDK 下载地址
查看>>
solr4.5分组查询、统计功能介绍
查看>>
Tomcat Server.xml详解
查看>>
CSS媒体查询(@media)
查看>>
如何提取一个转录本的3'UTR区域的序列
查看>>
得到当前日期前一天的零时零分零秒及当前日的零时零分零秒
查看>>
内存堆与栈的区别
查看>>
NHibernate初学者指南(12):日志
查看>>
30 个设计新颖的网站风格展示
查看>>
概念——统一资源定位符(Uniform / Universal Resource Locator,URL)
查看>>
Apache HttpComponents 获取Cookie
查看>>