美文网首页
原生javascript实现无缝轮播

原生javascript实现无缝轮播

作者: VickyFan | 来源:发表于2018-08-05 00:17 被阅读0次
    1.为什么要实现无缝轮播?
     轮播图,是一种展示内容的一种容器,当然你页可以理解他为一本书。特别是在一些门户网站主页、电商商品页,为了在一定范围内区域内展示更多的内容而存在。今天我们不关注展示的内容,而是关注轮播的展示形式。
    
        之前写过一个简单的轮播,右滑只能到最后一张,若想要回到第一张,则必须要点击左滑按钮。那这样的交互效果就特别僵硬,体验性特别不好。为我们想要的效果是一直点击右滑的时候,能从最后一张顺利的接入第一张,就像“纸张传球”的游戏一样。
    
    2.无缝轮播解决思路
    

    (1)克隆第一张图片至最后一张后面;
    (2)默认当前显示图片index=0,向后滚动index++,向前滚动index--;
    (3)当index==所有图片的个数(即之前已经显示过克隆的图片,此时应该显示第二张),所以让index==1(第二张图),整个盒子left=0,然后再移动;
    (4)记住,移动的过渡效果不要用transition来设置,这样则不会形成无缝;我们应该利用setInterval来显示每一次盒子应该在什么位置;

    3.代码结构
    html:

      <div id="box">
        <ul id="banner-box">
          <li>banner01</li>
          <li>banner02</li>
          <li>banner03</li>
          <li>banner04</li>
          <li>banner05</li>
        </ul>
        <span id="prev">&lt;</span>
        <span id="next">&gt;</span>
      </div>
    

    css:

    * {
      margin: 0;
      padding: 0;
    }
    
    li {
      list-style: none;
      float: left;
    }
    
    #box {
      width: 500px;
      height: 300px;
      border: 1px solid #000;
      overflow: hidden;
      position: relative;
      margin: 100px auto;
    }
    
    #prev,
    #next {
      display: block;
      width: 30px;
      height: 30px;
      border-radius: 50%;
      background: #666;
      color: #fff;
      font-size: 25px;
      text-align: center;
      line-height: 30px;
      position: absolute;
      top: 50%;
      margin-top: -15px;
      cursor: pointer;
    }
    
    #prev {
      left: 20px;
    }
    
    #next {
      right: 20px;
    }
    
    #banner-box {
      height: 100%;
      position: absolute;
      left: 0;
    }
    
    #banner-box li {
      height: 100%;
      width: 500px;
      background: #ddd;
      line-height: 300px;
      text-align: center;
    }
    

    js:

    <script>
      window.onload = function() {
        // 初始化轮播
        let oBox = document.getElementById('box');
        let oUl = document.getElementById('banner-box');
        let oLi = oUl.children;
        let prev = document.getElementById('prev');
        let next = document.getElementById('next');
        let timer = null;
        let index = 0;
        oUl.appendChild(oLi[0].cloneNode(true))
        oUl.style.width = oLi[0].offsetWidth * oLi.length +'px';
        oUl.style.left = 0;
        //向前滚动
        prev.onclick = function () {
          index--;
          move();
        }
        //向后滚动
        next.onclick = function () {
          index++;
          move();
        }
        //自动轮播
        function autoPlay () {
          timer = setInterval (() => {
            index++;
            move();
          }, 2000) 
        }
        autoPlay();
        oBox.onmouseover = function(){
            clearInterval(timer);
        }
        oBox.onmouseout = autoPlay;
        //运动函数
        function move () {
          if (index === oLi.length) {
            oUl.style.left = 0;
            index = 1;
          } else if (index === -1) {
            oUl.style.left = -(oLi.length - 1) * oLi[0].offsetWidth + 'px';
            index = oLi.length - 2;
          }
          animate(oUl, -index * oLi[0].offsetWidth);
        }
        function animate (obj, target){
          clearInterval(obj.timer);
          obj.timer = setInterval(function(){
              let speed = (target - parseInt(obj.style.left)) / 8;
              speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
              if (parseInt(obj.style.left) == target) {
                clearInterval(obj.timer);
              } else {
                obj.style.left = parseInt(obj.style.left) + speed + 'px';
              }
          },30);
        }
      }
    </script>
    
    image.png

    4.实现功能:
    (1)自动轮播
    (2)左右点击手动轮播

    之前写过好几次轮播,思路也是正确的,但是每次从最后一张跳转至第一张时候,就会向左滚动返回至第一张,根本就没有无缝。查明了原因,发现我是给ul加了一个transition属性,没有用setInterval来计算ul每一次移动的位置。下一篇会增加指示器上去,通过点击指示器到指定图片,同时根据当前图片高亮显示指示器......

    相关文章

      网友评论

          本文标题:原生javascript实现无缝轮播

          本文链接:https://www.haomeiwen.com/subject/ibyvvftx.html