[React] 如何实现一个已读进度条?

  |   0 评论   |   0 浏览   |   Erioifpud

效果预览

See the Pen Read progress by Erioifpud (@erioifpud) on CodePen.

介绍

这个功能很常见,一些自搭建的博客中就有,能让用户大概了解自己阅读的位置,它做起来也非常简单。

我这里假设你已经了解了元素尺寸与位置相关的属性,那么你只需要使用这些属性进行简单的加减法的运算,就能得到用户在容器中滚动的位置,依靠这个位置就能将进度条给画出来。

如果你不了解元素的尺寸与位置的相关属性,那也没关系。我做过一个相关的项目:交互式演练场,你可以在这里以可视化的方式去学习、理解这些属性。

解析

虽然这个进度条是加载页面上的统计整一篇文章的阅读进度,但是我们可以按组件的思维去做,这样更加灵活,在原理上也并没有差异。

那么首先我们得知道应该如何确定阅读的进度?这个很好理解,用户看完了多少内容,那么它的阅读进度就是多少,这个可以根据容器上方滚动部分的高度来确定(默认用户的阅读方向是垂直的),相关属性是 scrollTop

第二步我们需要确定 scrollTop 的范围,最小值是 0,表示没有滚动,那么最大值怎么确定呢?

我们以容器全屏显示作为前提条件,想象一下,在用户将页面滚动到最底部时滚动出去的部分的高度,加上视口中能显示的高度,他肯定是等于这个文档内容的总长度(总长度将可见与不可见的内容都包括了)的,可以参考以下两图:

stlRjs.png

stl2cj.png

把前提条件换成容器内,那么就是滚动出去的部分的高度 scrollTop,加上容器中能显示的高度 clientHeight,一定等于容器内容的总长度 scrollHeight

这三者里面会变的只有“滚动出去的部分的高度 scrollTop”,其他两个都是定值(在容器尺寸不变的情况下),所以我们可以确定 scrollTop 的最大值为 scrollHeight - clientHeight

那么接下来就是将 scrollTop 的取值范围映射到 [0, 100] 上了,简单的计算。

关键代码就在 handleScroll 中:

handleScroll () {
  const el = this.contentRef.current
  const fullHeight = el.scrollHeight - el.clientHeight
  const percent = el.scrollTop / fullHeight * 100
  this.setState({
    progress: parseFloat(percent.toFixed(2))
  })
}

接着监听容器内的 scroll 事件,将函数与事件做绑定就完成了。


标题:[React] 如何实现一个已读进度条?
作者:Erioifpud
地址:https://blog.doiduoyi.com/articles/1610503413252.html

评论

发表评论