Using jQuery is there a way to find the farthest (deepest, or most nested) child element?

后端 未结 5 754
南笙
南笙 2020-12-11 11:25

If I have a set of elements:

Text 1
5条回答
  •  心在旅途
    2020-12-11 12:03

    Here's an implementation that uses a treeWalk function I had written earlier and then wraps it in a jquery method that finds the deepest descendant of each item in the passed in jQuery object and returns a new jQuery object containing those nodes.

    A solution with recursion and lots of jQuery can be done with lots less code, but it will likely be slower. This is based on a generic native JS tree walk function that walks a tree.

    Working demo with more complicated HTML test case than the OP's HTML: http://jsfiddle.net/jfriend00/8tC3a/

    $.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;
                    }
                }
            }
        }
    })();
    
    var deeps = $(".start").findDeepest();
    
    deeps.each(function(i,v){
        $("#results").append(
            $("
  • ").html($(v).prop("tagName") + " " + $(v).html()) ); });
提交回复
热议问题