移动端实现自定义滚动条

1,884 阅读1分钟

背景

当内容高度超出容器的高度时并且容器设置了 overflow:scroll; 时会出现滚动条,但在移动端滚动条可能会被隐藏。但有一些场景可能确实需要滚动条的提示作用,例如下图需要用户输入一些信息,如果没有滚动条,用户就不会知道自己的还有未输项造成信息漏输。

效果预览图

如何实现一个滚动条呢? 我们需要实现一下几点:

  1. 滚动条由轨道 和 滑块组成
  2. 滑块高度占轨道的比重 = 容器的可见总高度/容器可滑动高度
  3. 滑块随滑动移动顺滑移动

思路

1. 计算滑块高度占轨道的比重

容器可滑动高度,可以使用 scrollDom.scrollHeight 获取

容器可视高度,使用 getComputedStyle(scrollDom).height 获取

注意dom.style.height 无法获取通过css设置的高度

scroll.gif

2. 内容滚动时移动滑块

使用 window.requestAnimationFrame 在每一次渲染的时候更新滑块的位置,这样滑动效果会比较顺滑。 通过scrollTop 属性计算出滑块应该滑动的比例。

function getMove(selector) {
    return function move() {
      // 容器可滑动高度
      var scrollHeight = document.querySelector(selector).scrollHeight;
      // 容器可视高度
      var domHeight = getComputedStyle(document.querySelector(selector)).height;
      domHeight = parseFloat(domHeight.substring(0, domHeight.length - 2));
      // 轨道高度
      var barHeight = getComputedStyle(document.querySelector(".scrollBar")).height;
      barHeight = parseFloat(barHeight.substring(0, barHeight.length - 2));
      
      // scrollTop
      var offsetY = document.querySelector(selector).scrollTop;
      
      // 更新滑块位置
      document.querySelector(".thumb").style.top = (barHeight * offsetY) / scrollHeight + "px";
      
      // 递归调用requestAnimationFrame
      window.requestAnimationFrame(getMove(selector));
    };
}
window.requestAnimationFrame(getMove(".remark_list"));

完整代码

完整代码