如何使用javascript创建html dom的叶节点数组

如何使用javascript创建html dom的叶节点数组,javascript,arrays,dom,recursion,tree,Javascript,Arrays,Dom,Recursion,Tree,所以我的问题基本上是,如何使用javascript函数返回html文档中所有叶节点的数组。稍后我需要对该列表执行操作。例如,如果我有html: <body> <div> <div> <p id="para1"></p> </div> </div> <p id="para2"></p> </body> 然后,函

所以我的问题基本上是,如何使用javascript函数返回html文档中所有叶节点的数组。稍后我需要对该列表执行操作。例如,如果我有html:

<body>
   <div>
      <div>
         <p id="para1"></p>
      </div>
   </div>
   <p id="para2"></p>
</body>

然后,函数应该返回一个数组,其中包含id为para1和para2的两个节点


注意:我想要的是节点本身,而不是它们的id。虽然给定了id,但我可以提取节点,所以这不是一个大问题。

也许下面的方法可以工作

var paraEl=new Array();
for(i=0;i<document.getElementsByTagName("p").length;i++){
    paraEl[i]=document.getElementsByTagName("p")[i];
}
var paraEl=new Array();
对于(i=0;i我假设“叶节点”是指没有子元素的元素。在这种情况下,可以获取所有元素,然后遍历每个元素,检查它是否有子元素,如果没有,则将其添加到数组中:

var leaves = new Array();
var els = document.body.getElementsByTagName("*");
for (var i = 0; i < els.length; i++) {
    if (els[i].children.length === 0) {
        leaves.push(els[i]);
    }
}
var leaves=newarray();
var els=document.body.getElementsByTagName(“*”);
对于(变量i=0;i
因此,您似乎想知道如何将节点添加到数组并返回数组。只需始终从函数返回数组并合并它们:

function getLeaves(element) {
    if (element.children.length === 0) {
        return [element];
    }
    var leaves = [];
    for (var i = 0, l = element.children.length; i < l; i++) {
        leaves.push.apply(leaves, getLeaves(element.children[i]));
    }
    return leaves;
}
函数getLeaves(元素){ if(element.children.length==0){ 返回[元素]; } var叶=[]; for(var i=0,l=element.children.length;i

或者,您可以向下传递一个数组,当元素是左元素时,它只将自身添加到该数组中:

function getLeaves(element, arr) {
    // create an array if none is passed. This happens in the first call.
    arr = arr || [];
    if (element.children.length === 0) {
        arr.push(element);
    }
    var leaves = [];
    for (var i = 0, l = element.children.length; i < l; i++) {
        getLeaves(element.children[i], arr);
    }
    return arr;
}
函数getLeaves(元素,arr){ //如果没有传递,则创建一个数组。这在第一次调用中发生。 arr=arr | |[]; if(element.children.length==0){ arr.push(元素); } var叶=[]; for(var i=0,l=element.children.length;i

这里有一个简单的函数,用于获取leafNodes,您可以在其中查看所有节点,包括文本节点(这意味着它永远不会返回包含文本节点的元素):

工作演示:

仅供参考,
.filter()
方法需要IE9。如果要在早期版本的IE中使用此方法,可以为
.filter()
安装polyfill,或更改为手动迭代阵列


和,这里有一个版本,如果你不想考虑文本节点,那么你在寻找叶元素,即使它们中有文本节点:

function getLeafNodes(master) {
    var nodes = Array.prototype.slice.call(master.getElementsByTagName("*"), 0);
    var leafNodes = nodes.filter(function(elem) {
        if (elem.hasChildNodes()) {
            // see if any of the child nodes are elements
            for (var i = 0; i < elem.childNodes.length; i++) {
                if (elem.childNodes[i].nodeType == 1) {
                    // there is a child element, so return false to not include
                    // this parent element
                    return false;
                }
            }
        }
        return true;
    });
    return leafNodes;
}
函数getLeafNodes(主节点){ var nodes=Array.prototype.slice.call(master.getElementsByTagName(“*”),0); var leafNodes=nodes.filter(函数(elem){ if(elem.hasChildNodes()){ //查看是否有任何子节点是元素 for(var i=0;i 工作演示:


下面是一个忽略文本节点的递归解决方案:

function getLeafNodes(master) {
    var nodes = Array.prototype.slice.call(master.getElementsByTagName("*"), 0);
    var leafNodes = nodes.filter(function(elem) {
        return !elem.hasChildNodes();
    });
    return leafNodes;
}
function getLeafNodes(master) {
    var results = [];
    var children = master.childNodes;
    for (var i = 0; i < children.length; i++) {
        if (children[i].nodeType == 1) {
            var childLeafs = getLeafNodes(children[i]);
            if (childLeafs.length) {
                // if we had child leafs, then concat them onto our current results
                results = results.concat(childLeafs);
            } else {
                // if we didn't have child leafs, then this must be a leaf
                results.push(children[i]);
            }
        }
    }
    // if we didn't find any leaves at this level, then this must be a leaf
    if (!results.length) {
        results.push(master);
    }
    return results;
}
函数getLeafNodes(主节点){ var结果=[]; var children=master.childNodes; 对于(变量i=0;i
工作演示:

您到底遇到了什么问题?我假设您知道如何调用函数。我知道我必须使用某种递归,但如何在该递归函数中更新数组,使其在最终返回时仅包含叶节点