2010-04-12 94 views
12

我希望能夠識別給定的DOM節點是否已被添加/插入另一個節點,或者它是否新鮮出來document.createElement()或類似的,並沒有放在任何地方。Javascript:如何判斷一個節點對象是否已經插入文檔/另一個元素

在大多數瀏覽器中,只檢查parentNode是否有效。

if (!node.parentNode) { 
    // this node is not part of a larger document 
} 

然而,在Internet Explorer中出現新的元素,即使之後他們已經使用了document.createElement()創建已經有(類型DispHTMLDocument?)一個parentNode對象。

其他不錯的跨瀏覽器和可靠的方式?

編輯:看起來像Internet Explorer隱式創建DocumentFragment(nodeType爲11)並將其設置爲節點的parentNode屬性。

+0

我編輯了一些問題,因爲它沒有得到很好的表達。對不起,nickf誰提供了一個很好的答案,但我真正想要的東西矯枉過正! – thomasrutter 2010-04-12 06:33:08

回答

5

我已經找到了自己的問題的答案。抱歉!我似乎最近做了很多。

文檔片段有11節點類型,並且永遠不會插入到文檔中,以便您可以檢查它像這樣:

if (!node.parentNode || node.parentNode.nodeType == 11) { 
    // this node is floating free 
} 

,您只需要在要插入多個對等節點文檔片段。 IE隱式地爲所有新創建的節點創建一個。無論如何檢查11個作品的節點類型。

+0

如果感興趣的節點是嵌套的,則這可能不起作用。它的parentNode屬性將被定義,並且parentNode的節點類型可能不是11(元素節點或1例如)。尼克的解決方案似乎是知道節點是否連接的絕佳方式。 – Anurag 2010-04-12 06:41:13

+0

但這就是我想要的。如果它像你所說的那樣是「嵌套」的,我認爲它已經被插入到了一個元素中。我想檢測自由浮動的節點,並且我的定義是「沒有父節點」。現在由於IE的行爲,我不得不將這個定義擴展爲「沒有父母或者DocumentFragment作爲父母」。 – thomasrutter 2010-04-18 06:41:30

6

我認爲,即使沒有IE的弱點,檢查parentNode的存在可能是不夠的。例如:

var d = document.createElement('div'); 
var s = document.createElement('span'); 
d.appendChild(s); 
if (s.parentNode) { 
    // this will run though it's not in the document 
} 

如果文檔中有某些內容,則最終其中的一個祖先將成爲文檔本身。試試這個,看看它是如何去:

function inDocument(node) { 
    var curr = node; 
    while (curr != null) { 
     curr = curr.parentNode; 
     if (curr == document) return true; 
    } 
    return false; 
} 

// usage: 
// if (inDocument(myNode)) { .. } 

如果你只想檢查到一定深度 - 也就是說,你知道你的新創建的元素不會被比IE的片段的任何進一步嵌套,試試這個:

function inDocument(node, depth) { 
    depth = depth || 1000; 
    var curr = node; 
    while ((curr != document) && --depth) { 
     curr = curr.parentNode; 
     if (curr == null) return false; 
    } 
    return true; 
} 

inDocument(myNode, 2); // check only up to two deep. 
inDocument(myNode);  // check up to 1000 deep. 
+0

謝謝nickf--對我而言,我只是擔心直接父母 - 我不介意它的祖父母或祖先是否不是文檔元素的一部分,只是該給定元素是否已被「附加」或'插入'在任何地方。換句話說,在你的第一個代碼示例中,我並不擔心d不會插入某處,因爲s *是*。 – thomasrutter 2010-04-12 06:20:49

+0

@thomasrutter在這種情況下,您可以在兩跳之後短路迴路。 IE創建的DocumentFragment的parentNode應該爲空。 – nickf 2010-04-12 06:22:18

+0

您的問題是「如何判斷節點是否已插入文檔中」的最簡潔的答案。我只是無法表達我真正想要的東西。 – thomasrutter 2010-04-12 06:30:56

2

DOM級別3引入compareDocumentPosition方法用於提供關於兩個節點如何彼此相關的位置信息的Node。其中一個返回值是DOCUMENT_POSITION_DISCONNECTED,這意味着節點之間沒有連接。可以利用這一點來檢查,如果一個節點沒有其他節點中使用包含:

Boolean(parent.compareDocumentPosition(descendant) & 16) 

DOCUMENT_POSITION_DISCONNECTED = 0x01; 
DOCUMENT_POSITION_PRECEDING = 0x02; 
DOCUMENT_POSITION_FOLLOWING = 0x04; 
DOCUMENT_POSITION_CONTAINS  = 0x08; 
DOCUMENT_POSITION_CONTAINED_BY = 0x10; 
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; 

谷歌曾撰文指出,可以發現contains功能的跨瀏覽器實現(我想,沒有提到IE的存在)在http://code.google.com/p/doctype-mirror/wiki/ArticleNodeContains。你可以利用它來進行檢查,如果給定節點的文件

.contains(document, someNode) 
0

後裔在什麼版本的IE瀏覽器是你測試此:


if (!node.parentNode) { 
    // this node is not part of a larger document 
} 
與舊版本的IE瀏覽器,你應該嘗試

也許是:


if (!node.parentElement) { 
    // this node is not part of a larger document 
} 

改爲。

雖然九,你會得到>>空< <用這兩種方法提供頂部創建容器元素不會被解析但後者又被翻譯成>>假< <完全按照你想要它。

相關問題