无缝轮播一直是面试的热门题目,而大部分答案都是复制第一张到最后。诚然,这种方法是很是标准,那么有没有另类一点的方法呢?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) }