innerHTML 的内部工作原理

Posted

技术标签:

【中文标题】innerHTML 的内部工作原理【英文标题】:Inner workings of innerHTML 【发布时间】:2011-08-29 04:06:48 【问题描述】:

我试图迭代地改变一个 Id 的 innerhtml,比如:

document.getElementById("test").innerHTML += "<br />"

document.getElementById("test").innerHTML += "<table>" + blahblah + "</table>"

但我发现它不一定把我的标签按顺序排列。

当然,这种方法很烂,我只是更改了所有内容以继续添加到一个字符串,我在最后将其分配给 Id 的 innerHTML。

我的问题是:

innerHTML 到底对我插入的标签做了什么,它是确定性的,是特定于浏览器的吗?

【问题讨论】:

请。举一个具体的例子。 WHAT 浏览器将哪些标签放入 WHAT 序列中? 【参考方案1】:

根据我的经验,大多数时候浏览器会在将 HTML1 注入 DOM 之前尝试更正它。如果您想以这种方式构建&lt;ul&gt;

someElement.innerHTML += '<ul>';
someElement.innerHTML += '<li>some li</li>';
someElement.innerHTML += '<li>some other li</li>';
someElement.innerHTML += '</ul>';

例如,Chrome 会导致:

<ul></ul>
 <li>some li</li>
 <li>some other li</li>
<ul></ul>

因此,innerHTML 可能会产生不可预知的结果,因为每次使用它时,浏览器都会更正 HTML(并且浏览器的处理方式也有所不同)。对于表格/表格元素尤其如此(在 IE 中尤其如此(顺便说一下,MS 发明了innerHTML;))。如果您希望您的 html 完全符合 的意图,请坚持使用 DOM 方法(createElement/appendChild 等),或者首先构建一个您想要的完整元素的字符串使用 innerHTML 插入,然后插入它,换句话说,不要将 innerHTML 与包含不完整 HTML 的字符串一起使用。

为了完整,我引用PPK's quirksmode:

如果您通过以下方式删除元素 IE中的innerHTML,它们的内容是 擦除,只有元素本身 (即开始和结束标签) 保持。如果要删除节点 您可能想重新插入 稍后,使用 DOM 方法,例如 删除子()

1 更具技术性:我认为每个浏览器都应用自己的HTML fragment parsing algorithm

【讨论】:

没错。此外,即使 innerHTML 属于 【参考方案2】:

InnerHTML 没有做任何事情,但是浏览器可以随意更改它喜欢的内容。如果您在 Firefox 中打开一个页面并同时打开 Firebug,您会看到这种情况。当您查看 HTML 时,您可能会发现某些元素甚至不再存在。

对于新手来说,Firefox 最令人惊讶的动作是将所有 HTML 更改为看起来像 XHTML 的内容。

至于你的方法,我觉得一点也不烂。事实上,我认为这很酷。那谢谢啦!

并对此表示赞成:-)

【讨论】:

除了我提出的问题之外,它不是一个好方法的原因是浏览器的处理速度比对 innerHTML 的分配要慢。 @Lance Roberts -- 我明白了。嗯,这很有意义。当然,当您计算“较慢”时,您将包括将 InnerHTML 从元素中取出并放入 var 的时间;将新的东西——在你的例子中是“”——放到那个 var 的末尾;并将 var 存储回 HTML。这真的是真的吗?浏览器是一只真正的狗——一只弓箭手——如果是这样的话。【参考方案3】:

我最近遇到了类似的问题。由于几乎没有任何有用的文档可用,我不得不从经验中学习。来了。

浏览器似乎会在进行任何修改后立即解析 innerHTML。通过这样的解析,任何无效的 HTML sn-p 都会被拒绝/添加到有效的 sn-p 中!

故事寓意:每当您修改innerHTML 时,请确保您插入的HTML 是有效的。因此,...innerHTML += "&lt;table&gt; ... &lt;/table&gt;"应该正常工作,但...innerHTML += "&lt;table&gt;"; ... .innerHTML += "&lt;\table&gt;"可能会导致意外行为。

这是因为在后一种情况下,只要您插入 &lt;table&gt;,浏览器就会解析字符串并添加一个完整的节点(从而完成您不完整的代码)。因此,您稍后添加的任何内容都将显示为表节点的兄弟节点,而不是您最初想要的子节点。

【讨论】:

【参考方案4】:

虽然innerHTML 不是 w3c DOM 的一部分,但所有浏览器都支持它。最初它只是将字符串 as-it-is 附加到您的元素中。然而,所有主要浏览器都会修改您的字符串并使该字符串成为有效的 html 标记。这是特定于浏览器的,没有在任何官方标准中明确定义。 我喜欢Mozilla 解释innerHTML 工作原理的方式。

【讨论】:

innerHTML 在 HTML5 中指定:w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml0【参考方案5】:

在我看来你不应该把文本放到 doucumet.getElementByID("Name").innerHTML 我认为你应该只输入html。 使用签名~它是 if you put in innerHTML something you can get some informations from API. Like me. In script tag. I used console.log and document.getElementById console.log('ID: ' + profile.getId()); console.log('Name: ' + profile.getName()); document.getElementById("Name").innerHTML =+profile.getName()+`

【讨论】:

以上是关于innerHTML 的内部工作原理的主要内容,如果未能解决你的问题,请参考以下文章

PHP的内部工作原理

简述ic卡芯片内部结构,工作原理及应用。

Worker的内部工作原理

简述ic卡芯片内部结构,工作原理及应用。

前端必读:浏览器内部工作原理

线程池内部工作原理