我在 div 元素上有一个滚动条。
在许多浏览器上(我在 MacOS 和 Linux 上的最新版本的 Chrome 和 Firefox 上对此进行了测试),浏览器似乎确保在滚动重绘触发之前调用绑定(bind)到 onscroll 的代码。
换句话说,下面的 fiddle 在滚动时既不闪烁也不闪烁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 v28 上,它确实会闪烁。几乎和我们使用 setTimeout (http://jsfiddle.net/m2E65/2/) 延迟滚动一样糟糕:
$('#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.出Document Object Model (DOM) Level 3 Events Specification W3C 文档:
A user agent must dispatch this event when a document view or an element has been scrolled. This event type is dispatched after the scroll has occurred.
我对这两句话的解释是,浏览器必须在滚动过程完成包容性重绘后调度 scroll
事件。
2。我认为没有办法确保在所有浏览器上,代码都会在重绘之前触发。也许你可以尝试捕捉用户滚动的所有方式,我想到了:
- 鼠标滚轮 ->
wheel
事件 - 通过选择文本 ->
mousedown
- 使用滚动条 -> 你可以希望
mousedown
会触发。
3。你的第一把 fiddle 闪烁给我:
- Safari 7.0.1
- iOS 7 上的 Safari
- 正如您在 Ubuntu 上的 Chrominum 中所说
它不闪烁:
- Firefox 27.0 Mac 和 Ubuntu
- Opera 19.0 Mac
- Chrome
现在它认为特别是 WebKit 浏览器(Chrome 除外)在调用 scroll
事件之前不会重新绘制,并且没有好的方法来防止这种情况。
关于javascript - "onscroll"在重绘之后或之前触发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21830056/