为了账号安全,请及时绑定邮箱和手机立即绑定

为什么“element.innerHTML + =”代码不好?

为什么“element.innerHTML + =”代码不好?

阿晨1998 2019-08-13 14:15:22
为什么“element.innerHTML + =”代码不好?我被告知不要使用element.innerHTML += ...这样的东西来附加东西:var str = "<div>hello world</div>";var elm = document.getElementById("targetID");elm.innerHTML += str; //not a good idea?这有什么问题?我还有其他选择吗?
查看完整描述

3 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

是的,这elm.innerHTML += str;是一个非常糟糕的主意。
使用elm.insertAdjacentHTML( 'beforeend', str )的完美替代品。

典型的“浏览器必须重建DOM”答案真的没有做正义的问题:

  1. 首先,浏览器需要遍历elm下的每个元素,每个属性,以及所有文本和注释以及进程节点,并转义它们以构建一个字符串。

  2. 然后你有一个长串,你追加到。这一步没问题。

  3. 第三,当你设置innerHTML时,浏览器必须删除它刚刚经历的所有元素,属性和节点。

  4. 然后它解析字符串,从它刚刚销毁的所有元素,属性和节点构建,以创建一个大多数相同的新DOM片段。

  5. 最后它附加新节点,浏览器必须布局整个事物。这可能是可以避免的(参见下面的替代方案),但即使附加的节点需要布局,旧节点也会将其布局属性缓存而不是从新鲜重新计算。

  6. 但还没有完成!浏览器还必须通过扫描所有 javascript变量来回收旧节点。

问题:

  • HTML可能无法反映某些属性,例如,当前值<input>将丢失并重置为HTML中的初始值。

  • 如果旧节点上有任何事件处理程序,它们将被销毁,您必须重新连接所有这些事件处理程序。

  • 如果您的js代码引用任何旧节点,它们将不会被销毁,而是会被孤立。它们属于文档但不再位于DOM树中。当您的代码访问它们时,不会发生任何事情或者它可能会引发错误。

  • 这两个问题都意味着它对js插件不友好 - 插件可能会附加处理程序或记住旧节点并导致内存泄漏。

  • 如果您养成使用innerHTML进行DOM操作的习惯,您可能会意外地更改属性或执行其他您不想要的操作。

  • 你拥有的节点越多,效率越低,电池就越多。

简而言之,它是低效的,它容易出错,它只是懒惰和不知情。


最好的选择是Element.insertAdjacentHTML,我没有看到其他答案提到:

elm.insertAdjacentHTML( 'beforeend', str )

几乎相同的代码,没有innerHTML的问题。没有重建,没有处理程序丢失,没有输入重置,更少的内存碎片,没有坏习惯,没有手动元素创建和分配。

它允许您将html字符串注入一行中的元素,包括属性,甚至允许yow注入复合元素和多个元素。它的速度得到了优化 - 在Mozilla的测试中,速度提高了150倍。

如果有人告诉你它不是跨浏览器,它是非常有用的,它是HTML5 标准,并且在所有浏览器可用。

不要再写elm.innerHTML+=了。


查看完整回答
反对 回复 2019-08-13
  • 3 回答
  • 0 关注
  • 959 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信