Skip to content Skip to sidebar Skip to footer

How To Create An Array Of Leaf Nodes Of An Html Dom Using Javascript

So my question is basically this, how can I return an array of all the leaf nodes of an html document using a javascript function. I need to perform operations on that list later.

Solution 1:

Here's a simple function to get leafNodes where you look at all nodes, including text nodes (this means it won't ever return an element that contains text nodes):

function getLeafNodes(master) {
    var nodes = Array.prototype.slice.call(master.getElementsByTagName("*"), 0);
    var leafNodes = nodes.filter(function(elem) {
        return !elem.hasChildNodes();
    });
    return leafNodes;
}

Working demo: http://jsfiddle.net/jfriend00/e9D5n/

FYI, the .filter() method requires IE9. If you want to use this method with earlier versions of IE, you can install a polyfill for .filter() or change to a manual iteration of the array.


And, here's a version if you don't want to consider text nodes, so you're looking for the leaf elements, even if they have text nodes in them:

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;
}

Working demo: http://jsfiddle.net/jfriend00/xu7rv/


And, here's a recursive solution that ignores text nodes:

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;
}

Working demo: http://jsfiddle.net/jfriend00/jNn8H/


Solution 2:

I assume by "leaf node", you mean an element with no children. In that case, you can get all elements, and then iterate through each one, check if it has any children, and if not add it to an array:

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]);
    }
}

Solution 3:

Perhaps the following will work?

var paraEl=new Array();
for(i=0;i<document.getElementsByTagName("p").length;i++){
    paraEl[i]=document.getElementsByTagName("p")[i];
}

But you know, document.getElementsByTagName("p") is already an array, right?


Solution 4:

So, it seems you are wondering how to add the nodes to the array and return the array. Simply always return an array from the function and merge them:

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;
}

DEMO

Alternatively, you can pass an array down and when the element is a leave, it just adds itself to it:

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;
}

DEMO


Post a Comment for "How To Create An Array Of Leaf Nodes Of An Html Dom Using Javascript"