If I have a set of elements:
<div class="start">
<div>
<span>Text 1</span>
</div>
</div>
<div class="start">
<span>
<div>
<span>Text 2</span>
</div>
<div>
<div>
<span>Text 3</span>
</div>
</div>
</span>
</div>
What is the best way (using jQuery) to retrieve the most nested child elements (in this case the spans "Text 1" and "Text 3") without knowing what the element structure will be beforehand specifically?
Here's a jsFiddle I'm working with.
Also, I apologize if this has been asked before, but I couldn't find anything like this question specifically.
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(
$("<li>").html($(v).prop("tagName") + " " + $(v).html())
);
});
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments