2012-12-30 74 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