JQuery发现(. .)遍历方法不包括当前节点-它从当前节点的子节点开始。调用在匹配算法中包含当前节点的 find 操作的最佳方式是什么?我看了所有的文件,没有什么能立刻让我想起来的。
我认为 andSelf是你想要的:
andSelf
obj.find(selector).andSelf()
请注意,无论当前节点是否与选择器匹配,这将始终重新添加当前节点。
你不能直接这样做,我能想到的最接近的方法是使用 .andSelf()调用 .filter(),像这样:
.andSelf()
.filter()
$(selector).find(oSelector).andSelf().filter(oSelector) //or... $(selector).find('*').andSelf().filter(oSelector);
不幸的是,.andSelf()没有选择器,这将很方便。
$('selector').find('otherSelector').add($('selector').filter('otherSelector'))
您可以将 $('selector')存储在一个变量中以提高速度。如果你非常需要的话,你甚至可以为它编写一个自定义函数:
$('selector')
$.fn.andFind = function(expr) { return this.find(expr).add(this.filter(expr)); }; $('selector').andFind('otherSelector')
对于 jQuery 1.8及以上版本,可以使用 .addBack()。它需要一个选择器,所以你不需要过滤结果:
.addBack()
object.find('selector').addBack('selector')
在 jQuery 1.8之前,你只能使用 .andSelf()(现在已经废弃和删除了) ,它需要过滤:
object.find('selector').andSelf().filter('selector')
我知道这是个老问题,但还有更正确的方法。如果顺序很重要,例如当你匹配像 :first这样的选择器时,我编写了一个小函数,它将返回与 find()实际包含当前元素集完全相同的结果:
: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是相当罕见的,不知道为什么。也许是因为之前有些人提到的性能问题。
andBack
(我现在注意到 TGR已经给出了第二个解决方案)
我试图找到一个 不会重复的解决方案(即不进入同一个选择器两次)。
这个小小的 jQuery 扩展就是这么做的:
jQuery.fn.findWithSelf = function(...args) { return this.pushStack(this.find(...args).add(this.filter(...args))); };
它将 find()(只有后代)与 filter()(只有当前集)结合起来,并且支持两个参数所吃的任何参数。pushStack()允许 .end()按预期工作。
filter()
pushStack()
.end()
使用方法如下:
$(element).findWithSelf('.target')