3 回答
TA贡献1891条经验 获得超3个赞
是的,这elm.innerHTML += str;
是一个非常糟糕的主意。
使用elm.insertAdjacentHTML( 'beforeend', str )
的完美替代品。
典型的“浏览器必须重建DOM”答案真的没有做正义的问题:
首先,浏览器需要遍历elm下的每个元素,每个属性,以及所有文本和注释以及进程节点,并转义它们以构建一个字符串。
然后你有一个长串,你追加到。这一步没问题。
第三,当你设置innerHTML时,浏览器必须删除它刚刚经历的所有元素,属性和节点。
然后它解析字符串,从它刚刚销毁的所有元素,属性和节点构建,以创建一个大多数相同的新DOM片段。
最后它附加新节点,浏览器必须布局整个事物。这可能是可以避免的(参见下面的替代方案),但即使附加的节点需要布局,旧节点也会将其布局属性缓存而不是从新鲜重新计算。
但还没有完成!浏览器还必须通过扫描所有 javascript变量来回收旧节点。
问题:
HTML可能无法反映某些属性,例如,当前值
<input>
将丢失并重置为HTML中的初始值。如果旧节点上有任何事件处理程序,它们将被销毁,您必须重新连接所有这些事件处理程序。
如果您的js代码引用任何旧节点,它们将不会被销毁,而是会被孤立。它们属于文档但不再位于DOM树中。当您的代码访问它们时,不会发生任何事情或者它可能会引发错误。
这两个问题都意味着它对js插件不友好 - 插件可能会附加处理程序或记住旧节点并导致内存泄漏。
如果您养成使用innerHTML进行DOM操作的习惯,您可能会意外地更改属性或执行其他您不想要的操作。
你拥有的节点越多,效率越低,电池就越多。
简而言之,它是低效的,它容易出错,它只是懒惰和不知情。
最好的选择是Element.insertAdjacentHTML
,我没有看到其他答案提到:
elm.insertAdjacentHTML( 'beforeend', str )
几乎相同的代码,没有innerHTML的问题。没有重建,没有处理程序丢失,没有输入重置,更少的内存碎片,没有坏习惯,没有手动元素创建和分配。
它允许您将html字符串注入一行中的元素,包括属性,甚至允许yow注入复合元素和多个元素。它的速度得到了优化 - 在Mozilla的测试中,速度提高了150倍。
如果有人告诉你它不是跨浏览器,它是非常有用的,它是HTML5 标准,并且在所有浏览器中都可用。
不要再写
elm.innerHTML+=
了。
添加回答
举报