类似于 jQuery .closest() 但遍历后代?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8961770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Similar to jQuery .closest() but traversing descendants?
提问by mamu
Is there a function similar to jQuery
.closest()
but for traversing descendants and returning only closest ones?
是否有类似于jQuery
.closest()
但用于遍历后代并仅返回最接近的函数的函数?
I know that there is .find()
function, but it returns all possible matches, not closest.
我知道有.find()
函数,但它返回所有可能的匹配项,而不是最接近的匹配项。
Edit:
编辑:
Here is definition of closest (at least for me):
这是最接近的定义(至少对我而言):
In first place all childrens are traversed, then each individuals childrens are traversed.
首先遍历所有孩子,然后遍历每个人的孩子。
In example given below id='2'
is closest .closest
descendants of id="find-my-closest-descendant"
在下面给出的例子中id='2'
是最近的.closest
后代id="find-my-closest-descendant"
<div id="find-my-closest-descendant">
<div>
<div class="closest" Id='1'></div>
</div>
<div class="closest" Id='2'></div>
</div>
Please see JSfiddle link.
请参阅JSfiddle 链接。
采纳答案by Rob W
According to your definition of closest
, I've written the following plugin:
根据您对 的定义closest
,我编写了以下插件:
(function($) {
$.fn.closest_descendent = function(filter) {
var $found = $(),
$currentSet = this; // Current place
while ($currentSet.length) {
$found = $currentSet.filter(filter);
if ($found.length) break; // At least one match: break loop
// Get all children of the current set
$currentSet = $currentSet.children();
}
return $found.first(); // Return first match of the collection
}
})(jQuery);
回答by James
If by "closest" descendant you mean the first child then you can do:
如果“最近的”后代是指第一个孩子,那么您可以这样做:
$('#foo').find(':first');
Or:
或者:
$('#foo').children().first();
Or, to look for the first occurrence of a specific element, you could do:
或者,要查找特定元素的第一次出现,您可以执行以下操作:
$('#foo').find('.whatever').first();
Or:
或者:
$('#foo').find('.whatever:first');
Really though, we need a solid definition of what "closest descendant" means.
但实际上,我们需要对“最近的后代”的含义有一个明确的定义。
E.g.
例如
<div id="foo">
<p>
<span></span>
</p>
<span></span>
</div>
Which <span>
would $('#foo').closestDescendent('span')
return?
哪个<span>
会$('#foo').closestDescendent('span')
回来?
回答by FishBasketGordo
You can use find
with the :first
selector:
您可以find
与:first
选择器一起使用:
$('#parent').find('p:first');
The above line will find the first <p>
element in the descendants of #parent
.
上面的行将找到<p>
的后代中的第一个元素#parent
。
回答by klawipo
What about this approach?
这种方法怎么样?
$('find-my-closest-descendant').find('> div');
This "direct child" selector works for me.
这个“直接子”选择器对我有用。
回答by ccjmne
Pure JS solution (using ES6).
纯 JS 解决方案(使用 ES6)。
export function closestDescendant(root, selector) {
const elements = [root];
let e;
do { e = elements.shift(); } while (!e.matches(selector) && elements.push(...e.children));
return e.matches(selector) ? e : null;
}
Example
例子
Considering the following structure:
考虑以下结构:
div ==├── div == │ ├── div │ ├── div.findme == │ ├── div │ └── div ├── div.findme == │ ├── div │ └── div └── div == ├── div ├── div └── divclosestDescendant(
, '.findme') === ; closestDescendant(, '.findme') === ; closestDescendant(, '.findme') === ; closestDescendant(, '.findme') === null;function closestDescendant(root, selector) { const elements = [root]; let e; do { e = elements.shift(); } while (!e.matches(selector) && elements.push(...e.children)); return e.matches(selector) ? e : null; } const [
, , , , ] = [0, 1, 2, 3, 4].map(x => document.querySelector(`#e${x}`)); console.log(closestDescendant(<div id="e0"> <div id="e1"> <div></div> <div id="e4" class="findme"></div> <div></div> <div></div> </div> <div id="e2" class="findme"> <div></div> <div></div> </div> <div id="e3"> <div></div> <div></div> <div></div> </div> </div>
, '.findme')); // console.log(closestDescendant(, '.findme')); // console.log(closestDescendant(, '.findme')); // console.log(closestDescendant(, '.findme')); // nullElement.prototype.QuerySelector_BreadthFirst = function(selector) { let currentLayerElements = [...this.childNodes]; while (currentLayerElements.length) { let firstMatchInLayer = currentLayerElements.find(a=>a.matches && a.matches(selector)); if (firstMatchInLayer) return firstMatchInLayer; currentLayerElements = currentLayerElements.reduce((acc, item)=>acc.concat([...item.childNodes]), []); } return null; };
$("#find-my-closest-descendant").siblings('.closest:first');
jQuery.fn.extend( {
closestChild_err : function( selector ) { // recursive, stack overflow when not found
var found = this.children( selector ).first();
if ( found.length == 0 ) {
found = this.children().closestChild( selector ).first(); // check all children
}
return found;
},
closestChild : function( selector ) {
var todo = this.children(); // start whith children, excluding this
while ( todo.length > 0 ) {
var found = todo.filter( selector );
if ( found.length > 0 ) { // found closest: happy
return found.first();
} else {
todo = todo.children();
}
}
return $();
},
});
$.fn.getNthClosestDescendants = function(n, type) {
var closestMatches = [];
var children = this.children();
recursiveMatch(children);
function recursiveMatch(children) {
var matches = children.filter(type);
if (
matches.length &&
closestMatches.length < n
) {
var neededMatches = n - closestMatches.length;
var matchesToAdd = matches.slice(0, neededMatches);
matchesToAdd.each(function() {
closestMatches.push(this);
});
}
if (closestMatches.length < n) {
var newChildren = children.children();
recursiveMatch(newChildren);
}
}
return closestMatches;
};
回答by Venryx
In case someone's looking for a pure JS solution (using ES6 instead of jQuery), here's the one I use:
如果有人正在寻找纯 JS 解决方案(使用 ES6 而不是 jQuery),这是我使用的:
##代码##回答by Jyoti watpade
You can just simply put,
你可以简单地说,
##代码##回答by Jean Paul A.K.A el_vete
There is an excellent article that points out that what the OP requires can be achieved easily with closest [Geeks for Geeks]
1https://www.geeksforgeeks.org/jquery-closest-with-examples/
有一篇很棒的文章指出,使用最接近的 [Geeks for Geeks]
1 https://www.geeksforgeeks.org/jquery-closest-with-examples/可以轻松实现 OP 所需的内容
回答by Eelco
Even though it's an old topic I could not resist implementing my closestChild. Delivers the first found descendant with least traveling ( breath first ). One is recursive (personal favorite ), other using a todo list so without recursion as jQquery extensions.
即使这是一个老话题,我也无法抗拒实现我的最接近的孩子。以最少的旅行(先呼吸)交付第一个找到的后代。一种是递归的(个人最喜欢的),另一种是使用待办事项列表,因此没有作为 jQquery 扩展的递归。
Hope someone benefits.
希望有人受益。
Note : The recursive gets stack overflow, and I improved the other, now simular to previous answer given.
注意:递归得到堆栈溢出,我改进了另一个,现在类似于先前给出的答案。
##代码##回答by cole
The following plugin returns the nth closest descendants.
以下插件返回第 n 个最近的后代。
##代码##