我想检索特定DIV元素中存在的所有节点。请参阅下面的测试页面 (火狐)
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<script>
function processTags()
{
var chNodes = document.getElementById('foo').childNodes ;
console.log(chNodes);
console.log("------");
var chNodes = document.getElementById('foo').getElementsByTagName('*') ;
console.log(chNodes);
}
</script>
</HEAD>
<BODY onload="processTags();">
<div id="foo">
<!-- this is a comment -->this is some text ? <span>this is inside span</span>
<div><p>test</p>test<div>
</div>
</BODY>
</HTML>
但它没有给我评论标签..检索所有标签的最佳方法是什么?
答案 0 :(得分:4)
问题的核心是这些方法......
document.getElementById(...)
document.getElementsByTagName(...)
...返回元素,如其名称所示。但是,注释和文本节点不是元素。它们是节点,但不是元素。
所以你需要像Vincent Robert建议的那样使用childNodes
做一些传统的老式DOM脚本。因为 - 正如你在评论中指出的那样 - .childNodes
只有一层'深层',你需要定义一个递归函数来查找注释节点:(我命名为document.getCommentNodes()
})
document.getCommentNodes = function() {
function traverseDom(curr_element) { // this is the recursive function
var comments = new Array();
// base case: node is a comment node
if (curr_element.nodeName == "#comment" || curr_element.nodeType == 8) {
// You need this OR because some browsers won't support either nodType or nodeName... I think...
comments[comments.length] = curr_element;
}
// recursive case: node is not a comment node
else if(curr_element.childNodes.length>0) {
for (var i = 0; i<curr_element.childNodes.length; i++) {
// adventures with recursion!
comments = comments.concat(traverseDom(curr_element.childNodes[i]));
}
}
return comments;
}
return traverseDom(document.getElementsByTagName("html")[0]);
}
答案 1 :(得分:3)
您可以使用.childNodes
来检索所有子项,而不是仅返回子元素的.getElementsByTagName('*')
。
这是一个检索DOM节点的所有后代的函数:
function getDescendantNodes(node)
{
var ret = [];
if( node )
{
var childNodes = node.childNodes;
for( var i = 0, l = childNodes.length; i < l; ++i )
{
var childNode = childNodes[i];
ret.push(childNode);
ret = ret.concat(getDescendantNodes(childNode));
}
}
return ret;
}
用法:
getDescendantNodes(document.getElementById("foo"));
答案 2 :(得分:3)
如果您不关心IE,可以使用TreeWalker
使用document.createTreeWalker
来避免递归方法并可能提高性能(未经测试):
function getCommentNodes(containerNode) {
var treeWalker = document.createTreeWalker(containerNode,
NodeFilter.SHOW_COMMENT, null, false);
var comments = [];
while (treeWalker.nextNode()) {
comments.push(treeWalker.currentNode);
}
return comments;
}
console.log(getCommentNodes(document.body));
答案 3 :(得分:1)
节点类型(非详尽):
getElementsByTagName
仅选择Element节点。 childNodes
,nextSibling
等等,可以获取各种节点。 nextElementSibling
只会选择元素。
答案 4 :(得分:0)
您需要使用innerHtml,然后使用解析器在其中查找注释。
答案 5 :(得分:0)
注释是DOM树中的节点,但它们没有标记名称。 getElementsByTagName
方法仅返回具有标记名称的节点。
如果您想要所有节点,则必须使用每个元素的childNodes
集合遍历DOM树。
答案 6 :(得分:0)
var getComments = function(oNode) {
var oChild,
aComments = [];
oNode = oNode || document;
for (var n=0; n<oNode.childNodes.length; n++) {
oChild = oNode.childNodes[n];
switch (oChild.nodeType) {
case 1: // Element
aComments = aComments.concat(getComments(oChild));
break;
case 8: // Comment
aComments.push(oChild);
break;
}
}
return aComments;
}