奇怪/不一致的scrollTop行为

时间:2013-11-04 11:21:51

标签: javascript browser dom-events

我在尝试滚动元素而不调用普通事件处理程序时偶然发现了这个

同时使用Firefox和IE10我在scrollTop方法操作方式上看到了一些非常奇怪的行为。例如,如果我在scrollTop aferwards 上设置div,请将scroll事件处理程序绑定到同一元素,处理程序会立即触发。根据我的测试,这个不会发生在Chrome上,这让我觉得FF和IE正在将最微小的动画应用到他们的卷轴上,或者这是某种错误。< / p>

See JSFiddle example。有趣的是,如果我在分配前设置1ms的超时,the problem goes away。我很想知道这里发生了什么,以及解决问题的最佳方法。

更新:从下面的评论中可能会发现这可能被认为是正常的浏览器行为,所以我会更新我的问题,询问这里发生了什么 - 请引用一些有趣的文章来更详细地解释这个过程

1 个答案:

答案 0 :(得分:8)

IE和FF中的内容如下:

  1. 调整了scrollTop属性
  2. 添加了滚动事件处理程序
  3. 执行功能完成。现在,浏览器有时间处理其他事情并将呈现页面。渲染导致同时提交滚动处理程序和scrollTop属性。因此,scrollTop更改会触发由处理程序捕获的滚动事件。
  4. 这与此代码不同:

    var dv = document.getElementsByTagName("div")[0];
    dv.scrollTop = dv.scrollHeight;
    setTimeout(function(){
        dv.onscroll = function() { 
        console.log("scrolled!");
    }, 0);
    

    以下情况如下:

    1. 调整了scrollTop属性
    2. setTimeout函数附加将onscroll事件处理程序添加到事件队列的函数。基本上推迟执行代码直到发生超时处理(另请参见较新的window.setImmediate)。
    3. 执行您的功能。现在,浏览器有时间处理其他事情并将呈现页面。渲染将触发滚动事件,但由于您的函数已延迟,因此尚未添加,因此没有捕获滚动事件。
    4. 渲染页面完成。现在,浏览器有时间处理其他事情,并将执行setTimeout设置的功能。这将添加onscroll事件处理程序,但由于scroll事件已被触发,因此不会调用事件处理程序。
    5. 有关此主题的更多信息,请参见herehere