2012-12-30 44 views
11

我正在管理Javascript中的名称列表。当您选中一个框时,您的名字将出现在列表中。当你取消选中时,它会被删除。当您将框设置为不确定状态时,您的名字被删除。克隆的节点不等于原始节点(使用isEqualNode)

我已经得到了隐藏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和铬测试。使用Firefox isEqualNode返回false,但使用Chromium它将返回true。感谢Felix指出了这一点。

+1

哪个浏览器?它似乎在Chrome中工作:http://jsfiddle.net/WhxQP/。 –

+0

有趣的问题。这里有一个简化的例子:http://jsfiddle.net/QtJJb/ –

+0

这个小提琴在Firefox 17.x中不起作用。 –

回答

0

比从未更好的迟到。:)

我不能用Firefox 17不再重现该问题,从而在评论中讨论这可能是在壁虎的错误,这则得到修复。

我不能然而发现任何bug报告。我将这个答案标记为现在可以接受,但是如果有人能够找到错误报告或解释发生了什么,我会接受。

BERGI的意见是正确的两个答案。

4

只是想出了这一点。根据specification,仅当两个元素具有相等数量的属性时,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 

http://jsfiddle.net/igorz/fxtDw/

+2

为什么应该不复制ids? W3规范没有这么说,甚至[Mozilla的参考](https://developer.mozilla.org/en-US/docs/DOM/Node.cloneNode)明确指出“*'cloneNode()'可能会导致重复文档中的元素ID *“。 – Bergi

2

在此Mozilla's reference写(感谢@Bergi)

通过cloneNode(返回重复的节点) 收到 当它被添加到另一个节点时,一个新的唯一ID

当你正在做一个追加时,id可能在此刻被改变。

+0

我认为这只是指内部'uniqueID'(如[这里](https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/NsIAccessNode#Attributes)),它不应该被'被认为是isEqualNode' – Bergi