为啥 DOM 更改后,IE 会丢弃 DOM 元素的 innerHTML/children?

Posted

技术标签:

【中文标题】为啥 DOM 更改后,IE 会丢弃 DOM 元素的 innerHTML/children?【英文标题】:Why does IE discard the innerHTML/children of a DOM element after DOM changes?为什么 DOM 更改后,IE 会丢弃 DOM 元素的 innerHTML/children? 【发布时间】:2014-09-29 19:32:12 【问题描述】:

我针对 IE、Chrome 和 Firefox 测试了以下代码,想知道是什么导致了结果的差异。

var body = document.getElementsByTagName('body')[0];
body.innerhtml = '<div id="myId"><span>I am a text</span></div>';
var divElement = document.getElementById('myId');

console.log(divElement.children.length); 
// All browsers say "1" !

body.innerHTML = ''; // just resetting the DOM

console.log(divElement.children.length); 
// Chrome and FF say "1", IE says "Sorry guys, it's 0"

不出意外,在三个浏览器中,在第二次innerHTML 更改后,divElement 对象不再引用渲染&lt;div&gt;。我对此没有任何问题。

我发现更有趣的是,IE 似乎丢弃了divElement 的孩子。 Chrome 和 FF 仍然允许我使用旧标签及其子标签,就像它们被渲染一样,但 IE 将标签变成了一个空壳。

浏览器处理导致此行为的 innerHTML 更改的方式可能有什么不同?

【问题讨论】:

由于phil 对新旧&lt;div&gt; 感到困惑,我已将问题更新为简单地设置innerHTML="" 这篇确切的帖子在 19:45 的第 9 频道谈话The Microsoft Edge Rendering Engine that makes the Web just work 中发表。 【参考方案1】:

IE 对innerHTML 属性采用了不同的方法(与其他浏览器相比)。虽然预期的操作是首先删除子节点(保留引用),然后设置新的 HTML 片段,但 IE 实际上似乎递归地destroy所有子节点,留下引用(如divElement示例)完全为空且无功能。 innerText 方法也有类似的效果。

我得到的最好的解释是MSDN post 声称在 IE 中,innerHTML 是一种 DHTML(不是 DOM)特性,也是一种低级破坏性方法。我知道innerHTML 是在 W3 DOM 规范之前实现的(回到 IE/Netscape 浏览器大战),但不知道这种低级行为是否是 IE 中的一些遗留实现。

不过,W3 doesn't say that the child nodes should be preserved or destroyed(这是最近的候选推荐,innerHTML was not part of HTML4 specification)。 W3 的其他参考资料也不是结论性的(至少我没有找到)。

【讨论】:

以上是关于为啥 DOM 更改后,IE 会丢弃 DOM 元素的 innerHTML/children?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 jQuery.val(value) 不会从 DOM 元素中分派任何事件?

更改DOM后刷新浏览器悬停效果

IE9 - 添加和删除 DOM 元素会破坏父 keydown 事件

查找正在更改 DOM 元素的 javascript

为啥自关闭 iframe 标记会阻止显示更多 DOM 元素?

设置dom元素可拖动,支持ie5+