admin管理员组文章数量:1312848
I am trying to run some code after I change the background of an element. I'd like to run the code after the background is changed visually, not just internally. Thus I'd like to wait for a repaint. I tried doing this using rAF, but that does not seem to be the correct way, because the code gets executed before the background color is changed visually (talking about milliseconds though).
I tried to achieve my goal with the following code (without luck):
requestAnimationFrame(() => {
document.getElementsByTagName("body")[0].style.backgroundColor =
"rgb(0, 75, 75)";
requestAnimationFrame(() => {
socket.emit("notify-black");
});
});
What would be the correct way of waiting for the repaint?
I am trying to run some code after I change the background of an element. I'd like to run the code after the background is changed visually, not just internally. Thus I'd like to wait for a repaint. I tried doing this using rAF, but that does not seem to be the correct way, because the code gets executed before the background color is changed visually (talking about milliseconds though).
I tried to achieve my goal with the following code (without luck):
requestAnimationFrame(() => {
document.getElementsByTagName("body")[0].style.backgroundColor =
"rgb(0, 75, 75)";
requestAnimationFrame(() => {
socket.emit("notify-black");
});
});
What would be the correct way of waiting for the repaint?
Share Improve this question asked Apr 17, 2020 at 21:38 Bram VanbilsenBram Vanbilsen 6,50514 gold badges57 silver badges96 bronze badges2 Answers
Reset to default 8requestAnimationFrame
will run its callback just before the next repaint. Put the code you want to run in a setTimeout
inside that, since the timeout callback will run almost immediately after the repaint finishes.
You can also use document.body
instead of document.getElementsByTagName("body")[0]
:
requestAnimationFrame(() => {
document.body.style.backgroundColor = "rgb(0, 75, 75)";
requestAnimationFrame(() => {
setTimeout(() => {
socket.emit("notify-black");
});
});
});
Live demo, using alert
(which blocks) instead of socket.emit
:
requestAnimationFrame(() => {
document.body.style.backgroundColor = "rgb(0, 75, 75)";
requestAnimationFrame(() => {
setTimeout(() => {
alert("notify-black");
});
});
});
Another example code that takes a screenshot using html2canvas. Open up example., open your console, and run the following:
const script = document.body.appendChild(document.createElement('script'));
script.src = 'https://html2canvas.hertzen./dist/html2canvas.js'
script.onload = () => {
requestAnimationFrame(() => {
document.body.style.backgroundColor = "rgb(0, 75, 75)";
requestAnimationFrame(() => {
setTimeout(() => {
html2canvas(document.querySelector("body")).then(canvas => {
document.write('<img src="'+canvas.toDataURL("image/png")+'"/>');
});
});
});
});
};
The best reliable and working answer including explanation i found, remend reading this https://www.webperf.tips/tip/measuring-paint-time/
And for reference in case the link isn't available anymore at some point:
/**
* Runs `callback` shortly after the next browser Frame is produced.
*/
function runAfterFramePaint(callback) {
// Queue a "before Render Steps" callback via requestAnimationFrame.
requestAnimationFrame(() => {
const messageChannel = new MessageChannel();
// Setup the callback to run in a Task
messageChannel.port1.onmessage = callback;
// Queue the Task on the Task Queue
messageChannel.port2.postMessage(undefined);
});
}
Use the following way:
elem.style.backgroundColor = 'red';
runAfterFramePaint(() => {
elem.style.backgroundColor = 'blue';
});
本文标签: htmlWaiting for repaint in JavascriptStack Overflow
版权声明:本文标题:html - Waiting for repaint in Javascript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741887153a2403087.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论