重新粉刷之后或之前"onscroll"被解雇?

ful*_*ton 7 javascript browser dom scroll

我在div元素上有一个滚动条.

在许多浏览器上(我在MacOS和Linux上的Chrome和Firefox的最新版本上进行了测试),似乎浏览器确保在滚动重绘触发之前调用绑定到onscroll的代码.

换句话说,当滚动http://jsfiddle.net/m2E65/1/时,以下小提琴不闪烁也不闪烁:

var onscroll = function() {
    var y = $("#container").scrollTop() + 30;
    var z = 0
    for (var c=0; c<y*10000; c++) {
        z+=c;
    }
    $("#label").text("bocal : "+z);
    $("#label").css("top", y);
};
$('#container').scroll(onscroll);
Run Code Online (Sandbox Code Playgroud)

但是在Ubuntu上的Linux Chromium v​​28上,它会闪烁.几乎和我们使用setTimeout(http://jsfiddle.net/m2E65/2/)延迟onscroll一样糟糕:

$('#container').scroll(function() {
    window.setTimeout(onscroll, 0);
});
Run Code Online (Sandbox Code Playgroud)

在这个相同的浏览器上,甚至使用http://jsfiddle.net/m2E65/4/中的 requestAnimationFrame也一样闪烁(见下文)

var onscroll = function() {
    var y = $("#container").scrollTop() + 30;
    var z = 0
    for (var c=0; c<y*10000; c++) {
        z+=c;
    }
    $("#label").text("bocal : "+z);
    $("#label").css("top", y);
    window.requestAnimationFrame(onscroll);
};
window.requestAnimationFrame(onscroll);
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 有这个规格吗?
  • 有没有办法确保在所有浏览器上,代码将在重绘之前运行?
  • 加分点:这种行为有多罕见?

idm*_*ean 4

1. 文档外对象模型 (DOM) 3 级事件规范W3C 文档:

当文档视图或元素滚动时,用户代理必须调度此事件。该事件类型在滚动发生调度。

我对这两句话的解释是,浏览器必须scroll在滚动过程完成包含重绘后调度该事件。

2.我认为没有办法确保在所有浏览器上,代码都会在重绘之前触发。也许你可以尝试捕捉用户可以自发滚动的所有方式,我想到了:

  • 鼠标滚轮 ->wheel事件
  • 通过选择文本->mousedown
  • 使用滚动条 -> 你只能希望它mousedown会触发。

3. 你的第一把小提琴在我面前闪烁:

  • Safari 7.0.1
  • iOS 7 上的 Safari
  • 正如你在 Ubuntu 上的 Chrominum 中所说

它不会闪烁:

  • Firefox 27.0 Mac 和 Ubuntu
  • 歌剧 19.0 Mac
  • 铬合金

现在它认为,特别是 WebKit 浏览器(Chrome 除外)在调用scroll事件之前不会重新绘制,并且没有好的方法来防止这种情况。