简体   繁体   中英

How to wait for DOM changes to render? (MutationObserver doesn't work)

I have a tree of DOM nodes, and delete a few children. I'd like to determine the updated size of the DOM tree.

MutationObserver doesn't work because it notifies on DOM model changes, but the rendering hasn't actually completed yet so the size isn't updated yet.

There are hacky ways to do this (setTimeout(delay), or multiple nested requestAnimationFrame()), but I don't want to run into unexpected sizing issues later on down the line.

Is there any non-hacky way to do this?

The updating of the box-layout, aka "reflow" can be triggered synchronously , and doesn't require a "full render". You can see this answer for more details on the synchronicity of the rendering operations.

So in your case, you can directly get the new sizes of your elements right after you did your DOM update, because this size getting will itself trigger a reflow; it's not even necessary to use a MutationObserver.

 const elem = document.getElementById('elem'); console.log('initial', elem.offsetHeight); elem.querySelectorAll('p:not(.notme)').forEach(el=>el.remove()); // getting '.offsetHeight' triggers a reflow console.log('after removing', elem.offsetHeight);
 <div id="elem"> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p class="notme">Hello</p> </div>

Though beware, triggering a reflow has some costs in terms of performance, so if you fear other things may also modify the DOM afterward, you may want to wait for the painting event-loop iteration, using requestAnimationFrame before calling one of the methods that do trigger it.

 const elem = document.getElementById('elem'); console.log('initial', elem.offsetHeight); elem.querySelectorAll('p:not(.notme)').forEach(el=>el.remove()); // wait the painting frame in case other operations also modify the DOM requestAnimationFrame(()=> { console.log('after removing', elem.offsetHeight); });
 <div id="elem"> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p class="notme">Hello</p> </div>


Ps: for the ones still interested in the Y of this XY problem, you can have a look at this Q/A which demonstrates the use of the upcoming requestPostAnimationFrame and offers a monkey-patch for it.

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