乐趣区

关于javascript:js使用transition效果实现无缝滚动

前言

无缝轮播始终是面试的热门题目,而大部分答案都是复制第一张到最初。诚然,这种办法是十分规范,那么有没有另类一点的办法呢?

第一种办法是须要把所有图片一张张摆好,而后缓缓挪动的,

然而我能不能间接不摆就硬挪动呢?

如果你应用过 vue 的transition,咱们是能够通过给每一张图片来增加入场动画和离场动画来模仿这个挪动

  • 进场动画就是从最右侧到屏幕地方
  • 出场动画是从屏幕地方到左侧移出

这样看起来的成果就是图片从左边始终往左挪动,然而这个不一样的中央是,咱们每一个元素都有这个进场动画和离场动画,咱们基本不必关怀它是第几个元素,你只管轮播就是。

如果不必 vue 呢?

很简略,咱们本人实现一个 transtition 的成果就好啦,次要做的是以下两点

  • 元素显示的时候,即 display 属性不为 none 的时候,增加 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属性,这个属性示意你的元素状态将放弃动画后的状态,如果不设置的话,动画跑完一遍,你的元素原本执行了来到动画,执行完当前会回来地方地位杵着。这个时候你会问了,下面的代码不是写了,动画执行完就暗藏元素吗?

如果你应用下面的 setTimeout 来命令元素执行完动画后隐没,那么 可能 会有一瞬间的闪动,因为理论业务中,你的代码可能比较复杂,setTimeout 没法在那么精准的工夫内执行。保险起见,就让元素放弃动画来到的最初状态,即translateX(-100%)。此时元素曾经在屏幕外了,不必关怀它的体现了

轮播逻辑怎么写?

很简略,咱们进一个新元素的时候同时移除旧元素即可,两者同时执行进场和离场动画即可。

 function autoPlay(){setTimeout(()=>{toggleShow(新元素, 旧元素)
         this.autoPlay()},DURATION) //DURATION 为动画间隔时间
 }
 function toggleShow(newE,oldE){
     // 旧 ele 和新 ele 同时动画
     hide(oldE)
     show(newE)
 }

 残缺代码

简略的无缝轮播

退出移动版