8

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

同时使用 Firefox 和 IE10,我在该scrollTop方法的运行方式中看到了一些非常奇怪的行为。例如,如果我设置scrollTopon adivaferwards,将scroll事件处理程序绑定到同一个元素,处理程序会立即触发。根据我的测试, Chrome不会发生这种情况,这让我认为 FF 和 IE 正在将最微小的动画应用到它们的滚动条上,或者这是某种错误。

请参阅 JSFiddle 示例。有趣的是,如果我在分配前设置了 1 毫秒的超时,问题就消失了。我很想知道这里发生了什么,以及修复它的最佳方法是什么。

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

4

1 回答 1

9

在 IE 和 FF 中发生的情况如下:

  1. scrollTop 属性调整
  2. 添加了滚动事件处理程序
  3. 函数的执行结束。现在,浏览器有时间处理其他事情并将呈现页面。呈现导致滚动处理程序和 scrollTop 属性同时提交。因此,scrollTop 更改触发了一个滚动事件,该事件由您的处理程序捕获。

这与此代码不同:

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 事件处理程序,但由于滚动事件已被触发,因此不会调用事件处理程序。

可以在此处此处找到有关该主题的更多信息。

于 2013-11-08T12:19:43.813 回答