2012-12-15 45 views
1

行,我有一點點功能遍歷樹是這樣的:與DOM節點遇到問題和的instanceof

function walkTree(node, func, args) { 
    func(node, args); 
    node = node.firstChild; 
    while (node) { 
     walkTree(node, func, args); 
     node = node.nextSibling; 
    } 
} 

而另一種功能,將拿起只有文本節點像這樣:

function selectTextNodes(node, nodes) { 
    if (node instanceof Text) { 
     nodes.push(node); 
    } 
} 

最後,同時使用:

texts = []; 
walkTree(body, selectTextNodes, texts); 

但是,它根本沒有填滿表!

如果我修改測試,以使用Node.nodeType這是可行的:

function selectTextNodes(node, nodes) { 
    if (node.nodeType == Node.TEXT_NODE) { 
     nodes.push(node); 
    } 
} 

在另一方面,在控制檯它是雙向的:

t = window.document.createTextNode("test"); 
r = (t.nodeType == Node.TEXT_NODE) && (t instanceof Text); 

即R是真的。

請注意,所有函數都嵌套在另一個接收body變量的函數中。在我的情況下,這是iframecontentDocument.body。沒有應用x域限制。

任何想法是怎麼回事?

回答

5

在不同的窗口中有不同的Text接口。因此,如果您的iframe文檔中有DOM節點,則不是instanceof window.Text,而是instanceof iframe.contentWindow.Text。 Afaik,作爲Javascript對象的Text接口的可用性也是非標準的。

這就是爲什麼你應該檢查元素的nodeType。但請注意,(舊?)IE不支持TEXT_NODE常量,因此您需要將其與3進行比較,或將該值作爲填充值指定爲Node.TEXT_NODE

+0

絕妙的回答!非常感謝! –

+0

嗯,這是非標準的,但已經[生活標準](https://developer.mozilla.org/en-US/docs/Web/API/Text)。 –

1

主文檔

<body> 
    <iframe name="ifr" id="ifr" src='test1.html'></iframe> 
    <button onclick="clkfn()">test</button> 

    <script> 

    function wrapper(body, iframeWindow) { 
     function walkTree(node, func, args) { 
     func(node, args); 
     node = node.firstChild; 
     while (node) { 
      walkTree(node, func, args); 
      node = node.nextSibling; 
     } 
     } 

     function selectTextNodes(node, nodes) { 
      if (node instanceof iframeWindow.Text) { 
       nodes.push(node); 
      } 
     }  

     texts = []; 
     walkTree(body, selectTextNodes, texts); 

     for (var i = 0; i < texts.length; i++) {  
     console.log("text #" + i + texts[i].nodeValue); 
     } 
    } 

    function clkfn() { 
     var ifr = frames["ifr"]; 
     wrapper(ifr.document.body, ifr); 
    } 

    </script> 


</body> 

的iFrame

<!doctype html> 
<html> 
    <head> 
    </head> 
    <body> 
     how are you? 
     I am fine. Thank you! 
    </body> 
</html> 

控制檯

當你點擊按鈕,控制檯打印:

text #0 
     how are you? 
     I am fine. Thank you! 

只有對代碼進行的更改纔會通過iframe正文和窗口。然後從iFrame窗口中引用Text對象。

+0

對不起,我應該更好地解釋。這段代碼實際上包含在一個接收body對象的函數中。實際上,body實際上是iframe的contentDocument.body。 –

+1

@AlbusDumbledore:現在用iFrame嘗試新代碼。將文本稱爲iFrameWindow.Text並且它可以工作。由於iFrame的參與,現在無法設置演示。 – closure

+0

感謝raghaw,這確實證實了Bergi說的。 –