多行列表垂直方向循环滚动 window.requestAnimationFrame

有这个需求的,请跳转到我的另一篇笔记关于无缝滚动的实用插件 and 如何快速找到合适的插件

以下纯纯是一个造轮子的过程,不用看了。。。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>scroll-list-demo</title>
  <style>
    ul, li {
      padding: 0;
      margin: 0
    }

    .roll-box {
      height: 100px;
      background: #007acc;
      overflow: hidden;
      color: #fff;
    }

    #roll li {
      height: 30px;
      border-bottom: 1px solid #ddd
    }
  </style>
</head>
<body>
<div class="roll-box">
  <ul id="roll">
    <li id="i-0">this is 0</li>
    <li id="i-1">this is 1</li>
    <li id="i-2">this is 2</li>
    <li id="i-3">this is 3</li>
    <li id="i-4">this is 4</li>
    <li id="i-5">this is 5</li>
  </ul>
</div>

<script>
roll();

function roll() {
  // 需要注意的是,这里的高度设置要同css里设置的是一样的,如果li的高度设置的不一样,则会出现动画抖动的现象
  var UL_HEIGHT = 100, LI_HEIGHT = 30;

  var ulObj = document.getElementById('roll');

  var height = ulObj.offsetHeight;
  var move = 0, oneSteep = 0.5;
  var clearIn = '', mouseOut = true;

  // 添加鼠标操作相关事件
  ulObj.addEventListener('mouseenter', function () {
    mouseOut = false;
  });
  ulObj.addEventListener('mouseleave', function () {
    mouseOut = true;
    animationRoll();
  });
  ulObj.addEventListener('click', function (e) {
    if (e.target.nodeName === 'LI') {
      alert('id is:' + e.target.id);
    }
  });

  // 滚动步骤
  // 1.将外部 ul 移动一个li的高度的距离
  // 2.将移出的li元素放到最后,实现循环,并复原ul的移动距离。
  function animationRoll() {
    function moveFn() {
      if (mouseOut) {
        move += oneSteep;
        ulObj.setAttribute('style', 'margin-top:-' + move + 'px');
        if (move >= LI_HEIGHT) {
          move = 0;
          ulObj.setAttribute('style', 'margin-top:-' + move + 'px');
          var temp = ulObj.children[0];
          ulObj.removeChild(temp);
          ulObj.appendChild(temp);
        }
        clearIn = window.requestAnimationFrame(moveFn);
      }
      else {
        window.cancelAnimationFrame(clearIn);
      }
    }

    window.cancelAnimationFrame(clearIn);
    clearIn = window.requestAnimationFrame(moveFn);
  }

  if (height > UL_HEIGHT) {
    animationRoll();
  }
  else {
    console.log(ulObj.offsetHeight);
  }
}
</script>
</body>
</html>

参考链接:
https://segmentfault.com/a/1190000021821797
https://codepen.io/Hewitt/pen/YdjLwN

扩展阅读:
requestAnimationFrame与setInterval的区别

posted @ 2022-09-15 14:57  近距离  阅读(116)  评论(0编辑  收藏  举报