如何等待DOM更改呈现? (MutationObserver不起作用)

问题描述 投票:1回答:1

我有一棵DOM节点树,并删除了几个子节点。我想确定DOM树的更新大小。

MutationObserver不起作用,因为它通知DOM模型更改,但是渲染尚未实际完成,因此大小尚未更新。

[有多种方法可以做到这一点(setTimeout(delay),或多个嵌套的requestAnimationFrame(),但是我不想在以后遇到意外的大小问题。

是否有任何非骇客的方式?

javascript jquery html dom
1个回答
0
投票

盒式布局的更新,也称为“重排”可以为triggered synchronously,不需要“完整渲染”。您可以在this answer中查看有关渲染操作同步性的更多详细信息。

因此,在您的情况下,您可以在进行DOM更新后直接获取元素的新大小,因为获取这种大小本身会触发重排;甚至没有必要使用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>

尽管请注意,触发重排在性能方面会付出一些代价,所以如果您担心其他事情之后还会修改DOM,则可能需要等待绘画事件循环迭代,使用requestAnimationFrame在调用以下内容之一之前触发它的方法。

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:对于仍然对这个XY问题的Y感兴趣的人,您可以看看this Q/A,它演示了即将推出的requestPostAnimationFrame的用法并为此提供了一个猴子补丁。

© www.soinside.com 2019 - 2024. All rights reserved.