背景
当内容高度超出容器的高度时并且容器设置了 overflow:scroll; 时会出现滚动条,但在移动端滚动条可能会被隐藏。但有一些场景可能确实需要滚动条的提示作用,例如下图需要用户输入一些信息,如果没有滚动条,用户就不会知道自己的还有未输项造成信息漏输。
效果预览图
如何实现一个滚动条呢? 我们需要实现一下几点:
- 滚动条由轨道 和 滑块组成
- 滑块高度占轨道的比重 = 容器的可见总高度/容器可滑动高度
- 滑块随滑动移动顺滑移动
思路
1. 计算滑块高度占轨道的比重
容器可滑动高度,可以使用 scrollDom.scrollHeight 获取
容器可视高度,使用 getComputedStyle(scrollDom).height 获取
注意
dom.style.height无法获取通过css设置的高度
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"));