简体   繁体   中英

Which is better to trigger relayouts in JavaScript - clientLeft hack or requestAnimationFrame?

Sometimes, when styles are applied via JavaScript, these changes are not visible because they occur within one animation frame.


Example:

$('.foo').style('color', 'red');
$('.foo').style('color', 'blue');

(Please keep in mind that this example is just for demo purposes in this question and not a real-world example.)


In the example above, color will be immediately changed to blue while red is never visible. Some people use setTimeout to work around this:

$('.foo').style('color', 'red');

setTimeout(function () {
  $('.foo').style('color', 'blue');
}, 1);

Since this is not a good practice, I wondered which is better to force the change in style to be drawn in the next frame?


Option 1: clientLeft hack

Requesting the clientLeft value of a DOM element will cause a relayout in the browser.

$('.foo').style('color', 'red');
var bar = $('.foo')[0].clientLeft; // hack to force relayout
$('.foo').style('color', 'blue');
  • Pro: "Just works" across browsers
  • Con: It's a hack

Option 2: requestAnimationFrame

$('.foo').style('color', 'red');

requestAnimationFrame(function () {
  $('.foo').style('color', 'blue');
});

I found that both solutions were not perfect because requestAnimationFrame is not supported on IE9 (and older) and the clientLeft hack is.. well it's a hack.

So, I used Paul Irish's polyfill for requestAnimationFrame and now I have the best of both worlds:

  • I can replace most of my setTimeout() calls with requestAnimationFrame()
  • Newer browsers that support it provide requestAnimationFrame natively
  • Older browsers get the polyfill

Perfect solution for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM