react滚动到指定位置_react 中 scrollTo 引发的思考

如何在 React 中实现 scrollTo 效果

之前考虑过用scrollInToView,但是由于这个 API 实现的场景不能控制元素在屏幕上的显示位置遂选择其他出路。

scrollTo 当只有一个元素需要直接滚动时 可以在 useEffect 直接调用 该方法即可。

当遇到需要控制一个有序数组的时候该如何操作。需求如下

  1. 可以点击按钮进行依次循环滚动。
  2. 需要控制住滚动时距离顶部的高度。
  3. 需要滚动的数组变化时,需要在滚动列表中添加或删除一条记录。

cd2f970cc71eaa4971197cc076628298.png

例如,在git MR 的详情页上有几个未解决的评论。在tab 页上需要一个快捷的点击按钮进行快速定位到需要解决的评论上去。

然而会遇到几个场景。

场景一:当页面上只需要定位到具体的某几条评论,不涉及评论解决后,跳转发生变化。这种是最简单的场景。我们实现的方案也会比较的简单。

即判定评论列表是否显示后,展示在 tab上一个跳转 btn 。然后把 未解决的评论通过一个字段筛选出来传入到一个记录的state 中. 其中通过 hook的 useEffect 计算出。一个未解决评论的位置数组。其中这个位置数组只根据 第一次 传入的 unResolved 计算一次。

这个时候你们可能会问怎么保证这个位置数组只计算一次。

// 设置一个 是否可以计算 dom 的标志位  
const [canCountDom, setCanCountDom] = useState(false)

  useEffect(() => {
    unResolved.length > 0 && setCanCountDom(true)
  }, [unResolved])

其中计算dom 位置的方法是下述代码

  useEffect(() => {
    unResolved.length > 0 && setBackUnResolved(unResolved)
    unResolved.length > 0 &&
      setDomPostionArr(
        unResolved.map((v) => {
          const dom = document.getElementById(v.id)
          const postion = dom && dom.getBoundingClientRect().top
          return { dom, postion }
        })
      )
  }, [canCountDom])

这样写的话是当未解决的数组有数据时,只计算出一次有数据时的位置信息。这样的话可以保证跟 gitlab上调整到未解决的下一个的效果一致。这样做法我们忽视了commit 列表上有两种搜索方法。

f944d40d09d1ac124cbdd7a1fd8a4ae3.png

按照时间,按照是否显示所有活动或者是只展示 diff 上评论四种场景。说了这么多其实就是评论的dom 可能在可视范围内消失。或者记录时的位置跟后面排序的位置不在同一个地方。例如时间倒序,原本的第一个未解决的评论就直接跳转到最后一个位置。这样咋们第一次记录的位置就无效了。

现在遇到的问题是这样的。react 中当滚动的元素已解决时整个滚动列表发生变化时

如果采用实时计算dom 位置的方法,当元素在可视范围的头部时,其值为 负。这个时候可能会说好解决直接向下滚动计算的负值不就可以了吗。那要是用户手动滚动到顶部你计算的负值瞬间没用了。。。


时间太紧,没有写完补充中。。。。


版权声明:本文为weixin_26854475原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。