轮播向右自动循环播放有啥好思路

来源:4-17 综合案例一(Swiper轮播图)

qq_凛冬将至_9

2024-03-01

西门老师,为了给加好样式的轮播组件动起来,我参照您最后手动设置transform的形式,写了一点js代码,我想实现:自动定时向右循环播放。
我的思路是:在轮播图列表最后多加一张第一张图,滑到最后,偷偷摸摸的切回到第一张图,这个切换会把过渡动画禁掉,延迟一下再打开。总体效果是实现了,就是偷偷切换回来会有稍微的延迟。
图片描述

代码实现,我贴下核心代码:
html

<div class="swiper-wrapper">
        <div class="swiper-slide"><img src="./imgs/1.jpg" alt=""></div>
        <div class="swiper-slide"><img src="./imgs/2.jpg" alt=""></div>
        <div class="swiper-slide"><img src="./imgs/3.jpg" alt=""></div>
        <!-- 多加一个第一张图 -->
        <div class="swiper-slide"><img src="./imgs/1.jpg" alt=""></div>
    </div>

js

// 获取wrapper元素
    const wrapper = document.querySelector('.swiper-wrapper')
    // 屏幕宽度
    const size = window.outerWidth
    // 自动播放10次(1秒一次)
    for (let i = 0; i < 10; i++) {
        setTimeout(() => {
            // 又回到第一张图的情况
            if (i > 0 && i % 3 === 0) {
                // 在10毫秒内偷偷摸摸切回到第一张图
                wrapper.classList.add('no-transition')
                wrapper.style.transform = 'translateX(0px)'
                setTimeout(() => {
                    wrapper.classList.remove('no-transition')
                    transform(i)
                }, 10)
                return
            }
            transform(i)
        }, 1000 * (i + 1))
    }

    function transform(i) {
        document.querySelector('.swiper-pagination-bullet.active').classList.remove('active')
        document.querySelector(`.swiper-pagination-bullet:nth-of-type(${(i + 1) % 3 + 1})`).classList.add('active')
        wrapper.style.transform = `translateX(-${size * (i % 3 + 1)}px)`
    }

禁用过渡的css

.no-transition {
    transition: none!important;
}

西门老师,除了这种办法,有没有更好的思路呢?

写回答

1回答

西门老舅

2024-03-03

你好,这一般是需要JS实现的,给你一个参考。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./iconfont.css">
  <style>
    *{ margin:0; padding:0;}
    ul, ol{ list-style: none;}
    img{ display: block;}
    .banner{ width: 520px; height:280px; margin: 30px auto; overflow: hidden; position: relative;}
    .banner ul{ width: 3640px; position: absolute; left: -520px;}
    .banner ul li{ float:left;}
    .banner ol{ position: absolute; bottom: 10px; width:100%; text-align: center;}
    .banner ol li{ width: 15px; height: 15px; border-radius: 50%; background: white; display: inline-block; box-sizing: border-box;}
    .banner ol li.active{ border:1px red solid; background: skyblue}
    .banner i{ position: absolute; top:47%; padding: 10px; background:rgba(0,0,0,0.5); color: white; display: none; cursor: pointer;}
    .banner i:nth-of-type(1){ left:0;}
    .banner i:nth-of-type(2){ right:0;}
  </style>
</head>
<body>
  <div class="banner">
    <ul>
      <li><img src="https://gtms02.alicdn.com/tps/i2/TB10vPXKpXXXXacXXXXvKyzTVXX-520-280.jpg" alt=""></li>
      <li><img src="https://img.alicdn.com/imgextra/i1/6000000004415/O1CN01JTTqpQ1iU7MFcZeqH_!!6000000004415-0-octopus.jpg" alt=""></li>
      <li><img src="https://gtms01.alicdn.com/tps/i1/TB1r4h8JXXXXXXoXXXXvKyzTVXX-520-280.jpg" alt=""></li>
      <li><img src="https://img.alicdn.com/imgextra/i1/6000000007379/O1CN01zUGonn24NdIP2SHVq_!!6000000007379-0-octopus.jpg" alt=""></li>
      <li><img src="https://gtms03.alicdn.com/tps/i3/TB1gXd1JXXXXXapXpXXvKyzTVXX-520-280.jpg" alt=""></li>
      <li><img src="https://gtms02.alicdn.com/tps/i2/TB10vPXKpXXXXacXXXXvKyzTVXX-520-280.jpg" alt=""></li>
      <li><img src="https://img.alicdn.com/imgextra/i1/6000000004415/O1CN01JTTqpQ1iU7MFcZeqH_!!6000000004415-0-octopus.jpg" alt=""></li>
    </ul>
    <ol>
      <li class="active"></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ol>
    <i class="iconfont icon-zuojiantou"></i>
    <i class="iconfont icon-youjiantou"></i>
  </div>
  <script>
    let banner = document.querySelector('.banner');
    let ul = document.querySelector('.banner ul');
    let ulLis = document.querySelectorAll('.banner ul li');
    let olLis = document.querySelectorAll('.banner ol li');
    let icons = document.querySelectorAll('.banner i');
    let now = 0;
    let now2 = 1;
    let move = moveFactory();
    for(let i=0;i<olLis.length;i++){
      olLis[i].onclick = function(){
        for(let i=0;i<olLis.length;i++){
          olLis[i].className = '';
        }
        this.className = 'active';
        move(ul, {left: -i*520}, 500, 'easeIn');
        now = i;
      };
    }
 
    banner.onmouseover = function(){
        icons[0].style.display = 'block';
        icons[1].style.display = 'block';
        clearInterval(timer);
    };
    banner.onmouseout = function(){
        icons[0].style.display = 'none';
        icons[1].style.display = 'none';
        timer = setInterval(leftRun, 3000);
    };
    icons[0].onclick = function(){
        rightRun();
    };
    icons[1].onclick = function(){
        leftRun();
    };
 
    let timer = setInterval(leftRun, 3000);
    function leftRun(){
        if(now === olLis.length-1){
            now = 0;
        }
        else{
            now++;
        }
        for(let i=0;i<olLis.length;i++){
            olLis[i].className = '';
        }
        olLis[now].className = 'active';
 
        now2++;
        move(ul, {left: -now2*520}, 500, 'easeIn', function(){
            if( now2 === ulLis.length - 1 ){
                ul.style.left = '-520px';
                now2 = 1;
            }
        });
    }
    function rightRun(){
        if(now === 0){
            now = olLis.length-1;
        }
        else{
            now--;
        }
        for(let i=0;i<olLis.length;i++){
            olLis[i].className = '';
        }
        olLis[now].className = 'active';
        now2--;
        move(ul, {left: -now2*520}, 500, 'easeIn', function(){
            if( now2 === 0 ){
                ul.style.left = - (ulLis.length - 2) * 520 + 'px';
                now2 = ulLis.length - 2;
            }
        });
    }
 
    function moveFactory(){
      let Tween = {    
        linear(t, b, c, d){  //匀速
            return c*t/d + b;
        },
        easeIn(t, b, c, d){  //加速曲线
            return c*(t/=d)*t + b;
        },
        easeOut(t, b, c, d){  //减速曲线
            return -c *(t/=d)*(t-2) + b;
        }
      }
      let timer;
      return function(elem, targets, time, fx, cb=function(){}){
        let t = 0;
        let d = time;
        let b = {};
        let c = {};
        for(let attr in targets){
          b[attr] = parseFloat(getComputedStyle(elem)[attr]);
          c[attr] = targets[attr] - b[attr];
        }
        let startNow = now();
        clearInterval(timer);
        timer = setInterval(()=>{
          let changeNow = now();
          t = Math.min( changeNow - startNow, d );
          for(let attr in targets){
            elem.style[attr] = Tween[fx](t, b[attr], c[attr], d) + (attr === 'opacity' ? '' : 'px');
          }
          if( t === d ){   //动画结束
            clearInterval(timer);
            cb();
          }
        }, 16);
        function now(){
          return new Date().getTime();
        }
      }
    }
 
  </script>
</body>
</html>


1
0

前端内功修炼 5大主流布局系统进阶

前端内功修炼:5大主流布局系统进阶

762 学习 · 239 问题

查看课程