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

时间:2014-02-17 13:13:56

标签: javascript dom scroll browser

我在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);

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

$('#container').scroll(function() {
    window.setTimeout(onscroll, 0);
});

在这个相同的浏览器上,即使像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);

我的问题是:

  • 这是否有规格?
  • 有没有办法确保在所有浏览器上,代码将在重绘前运行?
  • 奖励点:这种行为多么罕见?

1 个答案:

答案 0 :(得分:3)

1。在Document Object Model (DOM) Level 3 Events Specification W3C文件中:

  

用户代理必须在文档视图或文件视图时调度此事件   元素已滚动。此事件类型在 后发送   滚动已经发生。

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

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

  • 鼠标滚轮 - &gt; wheel事件
  • 选择文字 - &gt; mousedown
  • 使用滚动条 - &gt;你可以希望mousedown能够解雇。

3。你的第一个小提琴在我身上闪烁:

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

它没有闪烁:

  • Firefox 27.0 Mac和Ubuntu
  • Opera 19.0 Mac

现在它认为特别是WebKit-Browsers(Chrome除外)在调用scroll事件之前没有重新绘制,并且没有好办法防止这种情况发生。