Find Deepest Node

by Matthew Keefe

HTML

<div class="start">
    <div>
        <span><a href="#">Text 1</a></span>
    </div>
    <div>
        <span><a href="#"><b>Text 2</b></a></span>
    </div>
    <div>
        <span><a href="#">Text 3</a></span>
    </div>
    <div></div>
</div>

<div class="start">
    <span>
        <div>
            <span>Text 4</span>
        </div>
    </span>
</div>

<br/><br/><br/>

<span>Selected</span>
<ul id="results"></ul>

JavaScript

$.fn.findDeepest = function() {
    var results = [];
    this.each(function() {
        var deepLevel = 0;
        var deepNode = this;
        treeWalkFast(this, function(node, level) {
            if (level > deepLevel) {
                deepLevel = level;
                deepNode = node;
            }
        });
        results.push(deepNode);
    });
    return this.pushStack(results);
};

var treeWalkFast = (function() {
    // create closure for constants
    var skipTags = {"SCRIPT": true, "IFRAME": true, "OBJECT": true, "EMBED": true};
    return function(parent, fn, allNodes) {
        var node = parent.firstChild, nextNode;
        var level = 1;
        while (node && node != parent) {
            if (allNodes || node.nodeType === 1) {
                if (fn(node, level) === false) {
                    return(false);
                }
            }
            // if it's an element &&
            //    has children &&
            //    has a tagname && is not in the skipTags list
            //  then, we can enumerate children
            if (node.nodeType === 1 && node.firstChild && !(node.tagName && skipTags[node.tagName])) {                
                node = node.firstChild;
                ++level;
            } else if (node.nextSibling) {
                node = node.nextSibling;
            } else {
                // no child and no nextsibling
                // find parent that has a nextSibling
                --level;
                while ((node = node.parentNode) != parent) {
                    if (node.nextSibling) {
                        node = node.nextSibling;
                        break;
                    }
                    --level;
                }
            }
        }
    }
})();

// find deepest descendant of each .start node
var deeps = $(".start").findDeepest();

// output those deepest descendants so we can see what they are
deeps.each(function(i,v){
    $("#results").append(
       ...