Why does this repaint/reflow hack work?

流过昼夜 提交于 2020-01-23 03:02:04

问题


Sometimes we have to force repaint/reflow for the browser to render certain states. For instance:

window.onload = function () {
  setTimeout(function(){
    document.getElementById("gradient_text").innerHTML = "bar";
  }, 500);
}
#gradient_div {
  background: linear-gradient(#000000,#ffffff);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
<div id="gradient_div">
  <p id="gradient_text" onload="update">
    Foo
  </p>
</div>

The "gradient_text" element, refuses to visually update its text to "bar". In some cases, it's enough to trigger a synchronous repaint like so:

...
setTimeout(function(){
  var elem = document.getElementById("gradient_text");
  // sync force repaint hack
  elem.innerHTML="bar";
  elem.style.display = 'none';
  elem.style.display = 'block';
}, 500);
...

However, this does not work. Apparently, it requires an asynchronous hack:

window.onload = function () {
  setTimeout(function(){
    var elem = document.getElementById("gradient_text");
    elem.innerHTML = "bar";
    // async force repaint hack
    var display = elem.style.display;
    elem.style.display = 'none';
    setTimeout(function(){
      elem.style.display = display
    }, 50);
  }, 500);
}
#gradient_div {
  background: linear-gradient(#000000,#ffffff);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
<div id="gradient_div">
  <p id="gradient_text" onload="update">
    Foo
  </p>
</div>

What's causing the browser engine to behave this way? Mostly interested in Webkit/Blink.


回答1:


From my comment, should make it easy to test from any browser :

I added some mix-blend-mode effect so Firefox should render something similar to what Chrome is suppose to here .

window.onload = document.getElementById("gradient_text").innerHTML = "bar";
/*#gradient_div {
  background: linear-gradient(#000000,#ffffff);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
*/
/* UPDATE to show similar text-fill effect in Firefox */
#gradient_div {
  background: linear-gradient(#000000,#ffffff);
}
#gradient_text {
  background:white;
  mix-blend-mode:screen
}
<div id="gradient_div">
  <p id="gradient_text">
    Foo
   </p>
</div>


来源:https://stackoverflow.com/questions/38086610/why-does-this-repaint-reflow-hack-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!