node.appendChild 在 <= IE9 中的行为不符合预期(尚未检查 10)

发布于 2024-12-11 06:27:32 字数 2000 浏览 0 评论 0 原文

我遇到了一个非常奇怪的 IE 问题,我不知道根本原因是什么。我希望得到关于内部出了什么问题的解释。我可以将动态创建的元素追加到另一个元素一次,但任何后续尝试追加该节点都会删除追加到该节点的所有子元素。

我有一个函数创建一个包装 div,然后附加一个子“p”并附加一些文本。函数本质上是这样的:

function buildElement(text){
  var node,p,doc = document;
  node = doc.createElement('div');
  node.setAttribute('class','node-wrapper');

  p = doc.createElement('p');
  p.appendChild(doc.createTextNode(text));

  node.appendChild(p);
  return node;
}

它非常简单。这将构建一个包含您传递到其中的文本的元素。这是我想要做的事情的缩小版本,以及描述 IE 中发生的情况的注释:

// create a parent wrapper element
var wrapper = document.createElement('div');
wrapper.setAttribute('class','parent-wrapper');

var childNode = buildElement('This is a sample');

// This will append a child node with all of its children, 
// everything works as expected - ex:
// <div class="parent-wrapper">
//   <div class="node-wrapper">
//     <p>This is a sample</p>
//   </div>
// </div>
wrapper.appendChild(childNode);

// empty the parent wrapper
wrapper.innerHTML = '';

// re-append the childNode element to the parent wrapper
// in IE, this step will fill the parent node with just the node-wrapper element
// with the removed child node(s) - ex:
// <div class="parent-wrapper">
//   <div class="node-wrapper" />
// </div>
wrapper.appendChild(childNode);

如果运行此命令,您将看到的是第一个 wrapper.appendChild(childNode)效果很好,符合预期。但是第二次尝试追加子节点将导致 childNode 的子节点从 childNode 中删除。 (例如:“p”消失了。);
您可以在此处查看一个工作示例:
http://jsfiddle.net/jiggliemon/52ZPR/

奇怪的是你可以避免孩子-通过不附加 childNode,而是附加子节点的克隆来删除节点 wrapper.appendChild(childNode.cloneNode(true))
您可以在此处查看一个工作示例:
http://jsfiddle.net/jiggliemon/52ZPR/3/

这是一个更详细的示例:
http://jsfiddle.net/jiggliemon/bcSpQ/

Im having a really weird IE problem that I can't figure out what the root cause is. I'm hoping to get an explanation as to what internally is going wrong. I can append a dynamically created element to another once, but any subsequent attempts to append the node removes any children appended to it.

I have a function create a wrapper div, and then appends a child 'p' with some text attached to it. Function essentially reads like this:

function buildElement(text){
  var node,p,doc = document;
  node = doc.createElement('div');
  node.setAttribute('class','node-wrapper');

  p = doc.createElement('p');
  p.appendChild(doc.createTextNode(text));

  node.appendChild(p);
  return node;
}

It's pretty straight forward. This builds an element that contains the text that you pass into it. Heres a scaled down version of what I'm trying to do, and comments to describe what's happening in IE:

// create a parent wrapper element
var wrapper = document.createElement('div');
wrapper.setAttribute('class','parent-wrapper');

var childNode = buildElement('This is a sample');

// This will append a child node with all of its children, 
// everything works as expected - ex:
// <div class="parent-wrapper">
//   <div class="node-wrapper">
//     <p>This is a sample</p>
//   </div>
// </div>
wrapper.appendChild(childNode);

// empty the parent wrapper
wrapper.innerHTML = '';

// re-append the childNode element to the parent wrapper
// in IE, this step will fill the parent node with just the node-wrapper element
// with the removed child node(s) - ex:
// <div class="parent-wrapper">
//   <div class="node-wrapper" />
// </div>
wrapper.appendChild(childNode);

What you'll see if you run this, is that the first wrapper.appendChild(childNode) works great and as expected. But the second attempt to append the child node will result in the childNode's children being removed from the childNode. (ex: the 'p' is gone.);
You can see a working example of this here:
http://jsfiddle.net/jiggliemon/52ZPR/

What's weird is that you can avoid the child-node removal by not appending the childNode, but appending a Clone of the child node wrapper.appendChild(childNode.cloneNode(true)).
You can see a working example of this here:
http://jsfiddle.net/jiggliemon/52ZPR/3/

Here is a more elaborate example:
http://jsfiddle.net/jiggliemon/bcSpQ/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

撩动你心 2024-12-18 06:27:32

wrapper.innerHTML = ''

似乎损坏了您的内部节点。不要使用它。正确的技术是

for (var i = 0, len = wrapper.childNodes; i < len; i++) {
  wrapper.removeChild(wrapper.childNodes[i]);
}

这应该可以修复您的错误。

然而,除此之外说 innerHTML 是不好的!我无法解释你的错误。

HTML5 规范说:

删除正在设置innerHTML属性的节点的子节点,触发适当的突变事件。

所以它确实不应该损害 childNode

作为旁注:

p.textContent = text;

“相同”

p.appendChild(doc.createTextNode) (text));

想法

进一步来说,认为x.innerHTML = ''

是一种快速清空 x 的方法的 是一个谎言< /em>。

基准

请对第一个Child 使用 while 循环或设置 .textContent = ''

wrapper.innerHTML = ''

seems to damage your inner nodes. Don't use it. The correct technique is

for (var i = 0, len = wrapper.childNodes; i < len; i++) {
  wrapper.removeChild(wrapper.childNodes[i]);
}

This should fix your bug.

However other then saying innerHTML is bad! I can't explain your bug.

The HTML5 specification says :

Remove the child nodes of the node whose innerHTML attribute is being set, firing appropriate mutation events.

So it really should not be damaging childNode

As a side-note:

p.textContent = text;

is the "same" as

p.appendChild(doc.createTextNode(text));

As a further aside the idea that

x.innerHTML = ''

is a fast way to empty x is a lie.

Benchmark

Please use a while loop over the firstChild or set .textContent = ''

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文