無縫輪播一直是面試的熱門題目,而大部分答案都是複製第一張到最後。誠然,這種方法是很是標準,那麼有沒有另類一點的方法呢?javascript
第一種方法是須要把全部圖片一張張擺好,而後慢慢移動的,css
可是我能不能直接不擺就硬移動呢?vue
若是你使用過vue的transition
,咱們是能夠經過給每一張圖片來添加入場動畫和離場動畫來模擬這個移動java
這樣看起來的效果就是圖片從右邊一直往左移動,可是這個不同的地方是,咱們每個元素都有這個進場動畫和離場動畫,咱們根本不用關心它是第幾個元素,你只管輪播就是。git
很簡單,咱們本身實現一個transtition
的效果就好啦,主要作的是如下兩點github
xx-enter-active
動畫xx-leave-active
, 注意要讓動畫播完才消失function hide(el){ el.className = el.className.replace(' slide-enter-active','') el.className += ' slide-leave-active' el.addEventListener('animationend',animationEvent) } function animationEvent(e){ e.target.className = e.target.className.replace(' slide-leave-active','') e.target.style.display = 'none' e.target.removeEventListener('animationend',animationEvent) } function show(el){ el.style.display = 'flex' el.className += ' slide-enter-active' }
這裏咱們使用了animationend
來監聽動畫結束,注意這裏每次重新添加類的時候須要從新添加監聽器,否則會沒法監聽。若是不使用這個方法你可使用定時器的方式來移除leave-active類。面試
function hide(el){ el.className = el.className.replace(' slide-enter-active','') el.className += ' slide-leave-active' setTimeout(()=>{ //動畫結束後清除class el.className = el.className.replace(' slide-leave-active','') el.style.display = 'none' }, ANIMATION_TIME) //這個ANIMATION_TIME爲你在css中動畫執行的時間 }
.slide-enter-active{ position: absolute; animation: slideIn ease .5s forwards; } .slide-leave-active{ position: absolute; animation: slideOut ease .5s forwards; } @keyframes slideIn { 0%{ transform: translateX(100%); } 100%{ transform: translateX(0); } } @keyframes slideOut { 0%{ transform: translateX(0); } 100%{ transform: translateX(-100%); } }
須要注意的是這裏的 forwards
屬性,這個屬性表示你的元素狀態將保持動畫後的狀態,若是不設置的話,動畫跑完一遍,你的元素原本執行了離開動畫,執行完之後會回來中央位置杵着。這個時候你會問了,上面的代碼不是寫了,動畫執行完就隱藏元素嗎?less
若是你使用上面的setTimeout來命令元素執行完動畫後消失,那麼可能會有一瞬間的閃爍,由於實際業務中,你的代碼可能比較複雜,setTimeout無法在那麼精準的時間內執行。保險起見,就讓元素保持動畫離開的最後狀態,即translateX(-100%)
。此時元素已經在屏幕外了,不用關心它的表現了ide
很簡單,咱們進一個新元素的時候同時移除舊元素便可,二者同時執行進場和離場動畫便可。flex
function autoPlay(){ setTimeout(()=>{ toggleShow(新元素, 舊元素) this.autoPlay() },DURATION) //DURATION爲動畫間隔時間 } function toggleShow(newE,oldE){ //舊ele和新ele同時動畫 hide(oldE) show(newE) }