使用jQuery有没有办法找到最远(最深,或最嵌套)的子元素?
如果我有一组元素:
Text 1 Text 2 Text 3
什么是最好的方法(使用jQuery)来检索最嵌套的子元素(在这种情况下,跨越“文本1”和“文本3”),而不知道具体事先将是什么元素结构?
这是我正在使用的jsFiddle 。
另外,如果之前有人问过我,我会道歉,但我找不到具体的问题。
这是一个实现,它使用我之前编写的treeWalk函数,然后将其包装在jquery方法中,该方法查找传入的jQuery对象中每个项目的最深层后代,并返回包含这些节点的新jQuery对象。
使用递归和大量jQuery的解决方案可以使用更少的代码来完成,但它可能会更慢。 这是基于遍历树的通用本机JS树步行函数。
使用比OP的HTML更复杂的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()) ); });
您需要使用:last filter
$('.start').find(':last');
工作小提琴: http : //jsfiddle.net/BmEzd/1/
使用最少代码行的另一种方法(可能不那么快)可以如下:
var all_matched_elements = $(":contains('" + text_to_search + "')"); var all_parent_elements = $(all_matched_elements).parents(); var all_deepest_matches = $(all_matched_elements).not(all_parent_elements);
如果您的文本位于具有其他子元素的元素内,则此方法特别有用,如下所示:
Text 1Alpha Beta Gamma
但是,上面的代码不适用于如下所示的DOM:
search-text search-text
在上面的例子中,它只选择id为“#aaa”的最内层。 它会掉落“#zzz”。 如果还想选择id为“#zzz”,则必须修改开头的代码以从“all_parent_elements”中删除其直接文本也与搜索文本匹配的元素。
我认为这对你有用。
var deepestLevel = 0; var deepestLevelText = ""; function findDeepNested(element, currentLevel) { if ((element.children().length == 0) && (deepestLevel < currentLevel)) { // No children and current level is deeper than previous most nested level deepestLevelText="" + element.text() + " "; } else { // there are children, keep diving element.children().each( function () { findDeepNested($(this), currentLevel + 1); }); } } $(".start").each( function () { deepestLevel = 0; deepestLevelText = ""; findDeepNested($(this), 0); $("#results").append(deepestLevelText); });
小提琴