方才的輪播用具體頭腦做,由於不知道它有哪幾種狀況,就一步步來做,等結果做出來后,哪幾種狀況,一覽無餘。下面就用抽象頭腦做一遍.
用抽象頭腦做
初始化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})`\
末了優化下方才寫的代碼
<style>
*{
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;
}
<style>
<div class="window">
<div id="images" class="images">
<img class='png1' src="./images/1.png" width=400 alt="">
<img class='png2' src="./images/2.png" width=400 alt="">
<img class='png3' src="./images/3.png" width=400 alt="">
<img class='png4' src="./images/4.png" width=400 alt="">
<img class='png5' src="./images/5.png" width=400 alt="">
</div>
</div>
<script>
let n = 1;
int();
setInterval(function(){
makeLeave(getImage(n)).one('transitionend',function(e){
makeEnter($(e.currentTarget))
});
makeCurrent(getImage(n+1));
n++; //這裏n 是天然增進,讓它一向輪迴下去
},1000);
//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;
}
function getImage(n){
return $(`#images > img:nth-child(${x(n)})`)
}
function int(){
$(`#images > img:nth-child(${n})`).addClass('current').siblings().addClass('enter');
}
function makeLeave($node){
return $node.removeClass('current enter').addClass('leave')
}
function makeCurrent($node){
return $node.removeClass('enter leave').addClass('current')
}
function makeEnter($node){
return $node.addClass('enter').removeClass('leave current')
}
</script>
優化完了以後,現實代碼就只有這麼多,這個被稱為狀況機,如今再看輪播后,腦海里已自動變成了狀況機了。
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中的挪動方向即可,還能夠根據需要加上一些酷炫的操縱。