首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >节流滚动事件处理过程中的getBoundingClientRect

节流滚动事件处理过程中的getBoundingClientRect
EN

Stack Overflow用户
提问于 2018-02-08 15:01:38
回答 1查看 765关注 0票数 0

在我的项目开发过程中,我遇到了一个问题,这与调试期间有和没有预防性断点的getBoundingClientRect值之间的差异有关。为了尽量减少复制,我得到了跟踪。

代码语言:javascript
复制
const scrollHandler = () => {
  setTimeout(() => {
    const top = document.getElementById('test').getBoundingClientRect().top;
    console.log(top);
  });
};

document.getElementById('viewport').addEventListener('scroll', scrollHandler);

其中viewport只是固定高度的可滚动div。viewport的内容足够大,至少可以触发一个滚动事件。我还创建了柱塞演示。所有魔法都发生在setTimeout回调中。

现在是台阶。成功的情景。

  1. setTimeout回调开始时设置断点。
  2. 火卷轴事件。
  3. 进行“跨一步”以获得top值。
  4. 在控制台中执行document.getElementById('test').getBoundingClientRect().top
  5. 3和4的结果是相同的

失败的场景。

  1. setTimeout回调结束时设置断点。
  2. 火卷轴事件。
  3. 获取top变量的值(不需要任何操作)。
  4. 在控制台中执行document.getElementById('test').getBoundingClientRect().top
  5. 3和4的结果是不同的

为了避免对此复制产生任何误解,我用上述步骤录制了一个短片演示电影

在我的项目中,我在类似的环境(节流滚动事件)中进行计算,得到与预期不符的错误结果。但是当我调试它时,我得到了不同的画面;一个预防性的断点修正了计算。

这是一个bug还是已知的问题?还是我错过了什么?在这种情况下,我应该拒绝使用getBoundingClientRect吗?

EN

回答 1

Stack Overflow用户

发布于 2018-02-08 16:54:37

我不知道你想要的是什么,但假设你的滚动动画不像预期的那样工作。

有一个关于节流卷轴这里的提示是不正确的。假设你每隔30毫秒节流一次。如果页面在上一次动画之后停止滚动25毫秒,那么在它停止滚动之前,您将被困在滚动位置25毫秒内。

也许更好的方法是这样做(可以在本页的控制台中进行测试):

代码语言:javascript
复制
var ol = document.querySelectorAll("ol")[2];
window.onscroll = ((lastExecuted)=>{
    const expensiveHandler = e => {
      lastExecuted=Date.now();
      //do some animation maybe with requestAnimationFrame
      //  it may prevent overloading but could make animation
      //  glitchy if system is busy
      console.log("1:",ol.getBoundingClientRect().top);
    };
    var timerID
    return e=>{
      if(Date.now()-lastExecuted>19){
        //only animate once every 20 milliseconds
        clearTimeout(timerID);
        expensiveHandler(e);
      }else{
        //make sure the last scroll event does the right animation
        //  delay of 20 milliseconds
        console.log("nope")
        clearTimeout(timerID);//only the last is needed
        timerID=setTimeout(e=>expensiveHandler(e),20);
      }
    }
})(Date.now())
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48688505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档