寻找包含当前节点的 jQuery find (. .)方法

JQuery发现(. .)遍历方法不包括当前节点-它从当前节点的子节点开始。调用在匹配算法中包含当前节点的 find 操作的最佳方式是什么?我看了所有的文件,没有什么能立刻让我想起来的。

33990 次浏览

我认为 andSelf是你想要的:

obj.find(selector).andSelf()

请注意,无论当前节点是否与选择器匹配,这将始终重新添加当前节点。

你不能直接这样做,我能想到的最接近的方法是使用 .andSelf()调用 .filter(),像这样:

$(selector).find(oSelector).andSelf().filter(oSelector)
//or...
$(selector).find('*').andSelf().filter(oSelector);

不幸的是,.andSelf()没有选择器,这将很方便。

$('selector').find('otherSelector').add($('selector').filter('otherSelector'))

您可以将 $('selector')存储在一个变量中以提高速度。如果你非常需要的话,你甚至可以为它编写一个自定义函数:

$.fn.andFind = function(expr) {
return this.find(expr).add(this.filter(expr));
};


$('selector').andFind('otherSelector')

对于 jQuery 1.8及以上版本,可以使用 .addBack()。它需要一个选择器,所以你不需要过滤结果:

object.find('selector').addBack('selector')

在 jQuery 1.8之前,你只能使用 .andSelf()(现在已经废弃和删除了) ,它需要过滤:

object.find('selector').andSelf().filter('selector')

我知道这是个老问题,但还有更正确的方法。如果顺序很重要,例如当你匹配像 :first这样的选择器时,我编写了一个小函数,它将返回与 find()实际包含当前元素集完全相同的结果:

$.fn.findAll = function(selector) {
var $result = $();


for(var i = 0; i < this.length; i++) {
$result = $result.add(this.eq(i).filter(selector));
$result = $result.add(this.eq(i).find(selector));
}


return $result.filter(selector);
};

这无论如何都不会有效,但这是我能想到的最好的办法来维持正常的秩序。

这里有一个正确(但令人悲伤)的事实:

$(selector).parent().find(oSelector).filter($(selector).find('*'))

Http://jsfiddle.net/sergejcqmn/meqb8/2/

接受的答案是非常低效的,它会过滤已经匹配的元素集。

//find descendants that match the selector
var $selection = $context.find(selector);
//filter the parent/context based on the selector and add it
$selection = $selection.add($context.filter(selector);

定义一下

$.fn.findSelf = function(selector) {
var result = this.find(selector);
this.each(function() {
if ($(this).is(selector)) {
result.add($(this));
}
});
return result;
};

那就用

$.findSelf(selector);

而不是

$find(selector);

遗憾的是,jQuery 没有这种内置。经过这么多年的发展,真的很奇怪。我的 AJAX 处理程序没有应用到一些顶级元素,原因是。Find ()工作。

如果希望链接正常工作,请使用下面的代码片段。

$.fn.findBack = function(expr) {
var r = this.find(expr);
if (this.is(expr)) r = r.add(this);
return this.pushStack(r);
};

在调用 end 函数之后,它返回 # foo 元素。

$('#foo')
.findBack('.red')
.css('color', 'red')
.end()
.removeAttr('id');

如果没有定义额外的插件,那么您就会被这个问题所困扰。

$('#foo')
.find('.red')
.addBack('.red')
.css('color', 'red')
.end()
.end()
.removeAttr('id');

如果您严格地查看当前节点,那么您只需要这样做

$(html).filter('selector')

如果您正在寻找 只有一种元素,无论是当前元素还是其中的一个,您都可以使用:

result = elem.is(selector) ? elem : elem.find(selector);

如果你正在寻找 多种元素,你可以使用:

result = elem.filter(selector).add(elem.find(selector));

使用 andSelf/andBack是相当罕见的,不知道为什么。也许是因为之前有些人提到的性能问题。

(我现在注意到 TGR已经给出了第二个解决方案)

我试图找到一个 不会重复的解决方案(即不进入同一个选择器两次)。

这个小小的 jQuery 扩展就是这么做的:

jQuery.fn.findWithSelf = function(...args) {
return this.pushStack(this.find(...args).add(this.filter(...args)));
};

它将 find()(只有后代)与 filter()(只有当前集)结合起来,并且支持两个参数所吃的任何参数。pushStack()允许 .end()按预期工作。

使用方法如下:

$(element).findWithSelf('.target')