克隆节点不等于原始节点(使用isEqualNode)

时间:2012-12-30 15:58:37

标签: javascript html dom

我正在管理Javascript中的名称列表。选中复选框后,您的姓名将显示在列表中。当你取消选中它时,它会被划掉。当您将框设置为不确定状态时,您的名称将被删除。

我在隐藏的div中获得了当前登录用户的名称。名称是带有样式属性的跨度。

我用isEqualNode检查名称是否已经在列表中。当页面加载时它在列表中,它工作正常:找到名称,因此当框选中状态更改时更新名称。

for(var i=0 ; i < bullet.childNodes.length ; i++) {
    var node = bullet.childNodes[i];
    if(node.className == 'crossed')
        node = node.firstChild;
    if(node.isEqualNode(document.getElementById('curUser').firstChild))
        break;
}
// if i < bullet.childNodes.length, then we found the user's name in the list

如果名称不在列表中,我将克隆范围。

var newName = document.getElementById('curUser').firstChild.cloneNode(true);
bullet.appendChild(newName);

这在视觉上有效。

但我偶然发现了一些棘手的问题:newName.isEqualNode(document.getElementById('curUser').firstChild)是假的!因此,如果盒子状态再次改变,将无法找到新添加的名称,并且将再次创建一个新名称。

这是跨度的样子:

<span style="font-weight: bold ; color: #003380 ;">Pikrass</span>

目前我只是简单地检查一下(我可以检查跨度内的文本数据而不是依赖于isEqualNode),但我对为什么克隆节点可能与原始节点不同感兴趣,根据isEqualNode。

相关规范:cloneNodeisEqualNode


编辑:我使用Firefox和Chromium进行了测试。使用Firefox isEqualNode返回false,但使用Chromium它返回true。感谢Felix指出这一点。

3 个答案:

答案 0 :(得分:4)

刚想出来了。根据{{​​3}},isEqualNode仅在两个元素具有相同数量的属性时才返回true。但是如果源元素具有ID,则不会复制它,因为ID应该是唯一的,因此它具有较少的属性。使用类而不是ID它可以正常工作。

标记:

<div id="withId">withId content</div>
<div class="withoutId">withoutId content</div>

JS:

function test(node) {
    var copy = node.clone(true);
    document.body.appendChild(copy);
    console.log('are equal: ' + copy.isEqualNode(node)
        + ', attributes lengths: ' + node.attributes.length + ' ' + copy.attributes.length
        + ', ids: ' + node.getAttribute('id') + ' ' + copy.getAttribute('id'));
}

test(document.getElementById('withId'));
// are equal: false, attributes lengths: 1 0, ids: withId null

test(document.getElementsByClassName('withoutId')[0]);
// are equal: true, attributes lengths: 1 1, ids: null null

specification

答案 1 :(得分:2)

这里写的是Mozilla's reference(感谢@Bergi)

  

cloneNode()返回的重复节点在添加到另一个节点时会收到一个新的唯一ID

当你正在做追加时,id可能会在此时改变。

答案 2 :(得分:0)

迟到总比没有好。 :)

我无法再使用Firefox 17重现此问题,因此正如评论中所讨论的那样,这可能是Gecko中的一个错误,然后又被修复了。

但我找不到任何错误报告。我将此答案标记为现在已被接受,但如果有人能够找到错误报告或对引擎盖下发生的事情的解释,我会接受。

Bergi的评论适合其他两个答案。