我试图在DOM操作之后准确理解使用常规DOM更新的内容。
假设我们下面有DOM,我使用javascript删除带有蓝色类的li。
这是否意味着浏览器查看类blue的父级(例如:列表1的id)并重新呈现包含所有子级的DOM节点(减去蓝色类)然后根据任何css重新绘制整个页面规则是什么?
我认为这将是一个过程,但我不确定,无法在任何地方找到任何具体的例子。
<div>
<ul id="list1">
<li> red </li>
<li class="blue"> blue </li>
<li> green </li>
</ul>
<ul id="list2">
<li> orange </li>
<li> gray </li>
<li> brown </li>
</ul>
</div>
答案 0 :(得分:3)
这并不容易,这是因为您可能不太了解 DOM更新+呈现过程的工作原理。
DOM只是一个javascript对象,与其他任何对象一样。
当你使用DOM manips时,它真的就像你修改了普通对象的属性(复杂的属性,但仍然)。
这些manips中的一些可能确实弄脏了页面的布局和渲染帧,但通常浏览器会等到他们真正必须在触发这两种算法之前执行重绘操作。这意味着这些算法不会在每个DOM操作中被触发。
所以回答这个问题,当DOM被操纵时,你正在改变一个js对象的属性,并可能设置一个标志,让我们知道它们必须在下一个屏幕上启动的布局recalc和渲染器刷新。
当这些布局重新计算(又名 reflow )和实际启动的重绘操作不受任何规格限制时,大多数浏览器都会尝试这样做优化,因此很难对这些如何在任何地方工作有明确的说法。 (虽然规定in some cases回流应同步进行) 但是我们可以假设,如果没有任何可渲染的东西发生了变化,那么这些至少可以是捷径。
例如,如果在您的示例#list1
中将display
CSS属性设置为none
,则可能没有任何内容可以重新绘制,如果您重新附加了.blue
元素同步。
以不那么冗长的方式,
// js execution
DOM manip => mark layout as dirty
DOM manip => mark layout as dirty
... there may be a lot here
// Before screen refresh
if(layout.isDirty())
layout.recalc() // will itself mark repaint as dirty if needed
if(renderer.isDirty())
rendered.repaint()
答案 1 :(得分:0)
是的,因为这是你通过它的父母,即.removeChild()
删除元素的唯一方法。然后DOM可能会或可能不会经历所谓的Reflow,这取决于结果的变化。