I have a scrollbar on a div element.
On many browsers (I tested this on recent versions of Chrome and Firefox on MacOS and Linux), it seems like the browsers make sure that code bound to onscroll is called before the repaint trigger by the scrolling.
In other words, the following fiddle does not flicker nor blink when scrolling 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);
However on Linux Chromium v28 on Ubuntu, it does flicker. Almost as badly as if we deferred onscroll using setTimeout (http://jsfiddle.net/m2E65/2/) :
$('#container').scroll(function() {
window.setTimeout(onscroll, 0);
});
On this very same browser, even using requestAnimationFrame as in http://jsfiddle.net/m2E65/4/ flickers just as badly (see below)
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);
My question is :
- Is there a spec for this?
- Is there a way to ensure that on all browsers, the code will be run before repaint?
- Bonus point : how rare is this behavior?
1. Out of Document Object Model (DOM) Level 3 Events Specification W3C Document:
My interpretation of this two sentences is that a browser has to dispatch the
scroll
event after the scroll process completed inclusive repainting.2. I don't think there is way to ensure that on all browsers, the code will fire before repaint. Maybe you could try catching all ways a user can scroll, spontaneous I thought of:
wheel
eventmousedown
mousedown
will fire.3. Your first fiddle flickers to me on:
It does not flicker in:
Now it think that specially WebKit-Browsers (except Chrome) not repaint before calling the
scroll
event and that there is no good way to prevent this.