最新公告  | 
  • CTRL + D 加入收藏不迷路哦

  • 欢迎您光临码云笔记网,一个关注WEB前端开发的个人技术博客!

js使用transition效果实现无缝滚动

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)
 }

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>swiper</title>
  <style>
    .container{
      position: relative;
      overflow: hidden;
      height: 300px;
      overflow: hidden;
    }
    .item{
      width: 100%;
      font-size: 36px;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .item:nth-child(2n+1){
      background-color: gray;
    }
    .item:nth-child(2n){
      background-color: pink;
    }
    .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%);
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="item" style="display:flex" >1</div>
    <div class="item" style="display:none" >2</div>
    <div class="item" style="display:none" >3</div>
    <div class="item" style="display:none" >4</div>
  </div>
</body>
<script>
  const DURATION = 3000
  let list = document.querySelectorAll('.item')
  let curIndex = 0
  autoPlay()
  function autoPlay(){
    setTimeout(()=>{
      toggleShow(list[(curIndex+1)%list.length], list[curIndex])
      curIndex = (curIndex+1)%list.length
      this.autoPlay()
    },DURATION)
  }
  function toggleShow(newE,oldE){
    //旧ele和新ele同时动画
    hide(oldE)
    show(newE)
  }
  //离场
  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'
  }
</script>
</html>

作者:李大雷 原文链接:点击这里

1. 本站所有免费资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!
2. 本站不保证所提供下载的免费资源的准确性、安全性和完整性,免费资源仅供下载学习之用!如有链接无法下载、失效,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
4. 如果您也有好的资源或技术教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
5. 加入前端开发QQ群:565733884,我们大家一起来交流技术!
码云笔记 » js使用transition效果实现无缝滚动

发表评论