5

我需要检索第一个元素。

我用这段代码做到这一点......

$(element).find('.x').first();

据我了解,该代码...

  1. element从匹配的 中检索所有元素.x
  2. 删除不需要的元素;

有没有更好的方法呢?喜欢$.findOne()还是什么?

4

10 回答 10

11

根据 jQuery 文档:

因为 :first 是一个 jQuery 扩展而不是 CSS 规范的一部分,所以使用 :first 的查询不能利用原生 DOM querySelectorAll() 方法提供的性能提升。为了在使用 :first 选择元素时获得最佳性能,首先使用纯 CSS 选择器选择元素,然后使用 .filter(":first")。

因此,将您的选择器重写为:

$(element).find('.x').filter(":first")

或(这个只会给你直接后代,并且会比 快.find,除非你也在寻找嵌套元素)

$(element).children('.x').filter(":first")

应该会给你更好的结果。


更新kingjivpatrick dw的宝贵意见(见评论)之后,这两个似乎确实比.filter(':first')文档声称的要快。

$(element).find('.x').first();   // faster

$($(element).find('.x')[0]);     // fastest
于 2011-08-24T16:48:12.510 回答
4

如果你想让它真正快速,你应该使用本机浏览器方法。现代浏览器支持querySelector [docs]

var $result;
if(element.querySelector) {
    $result = $(element.querySelector('.x'));
}
else {
    $result = $(element).find('.x').first();
}

用法有点有限,因为它只有在element是单个元素并且选择器是有效的 CSS 选择器时才有效。你可以用它做一个插件。但是,如果您考虑所有情况,例如多个元素等,则可能不再具有优势。

同样,如果您有一个非常具体的用例,这可能很有用,如果没有,请坚持使用 jQuery。

更新:事实证明,制作插件仍然更快:jsPerf benchmark

(function($) {
    $.fn.findOne = function(selector) {
        try {
            var element, i = 0, l = this.length;
            while(i < l && (element = this[i].querySelector(selector)) === null) {
                i++;
            }
            return $(element);
        }
        catch(e) {
            return this.find(selector).first();
        }
    };
}(jQuery));

这是如何工作的:

该插件迭代选定的 DOM 元素并调用querySelector它们中的每一个。一旦找到一个元素,循环将终止并返回找到的元素。发生异常的原因有两个:

  • 浏览器不支持querySelector
  • 选择器不是纯 CSS 选择器

在这两种情况下,插件都会回退到使用普通的 jQuery 方法。

于 2011-08-24T17:08:32.650 回答
2

尽管看起来很疯狂,但在我见过的每一个性能测试中,.first()性能都比:first.

正如大多数人所建议的那样,似乎 using$(element).find(".x:first")应该具有更好的性能。但是,实际上.first更快。我还没有研究 jquery 的内部来找出原因。

http://jsperf.com/jquery-select-first

显然使用[0]然后重新包装在 jquery 对象中是最快的:

$($(element).find(".x")[0])

编辑:有关原因的解释,请参见 mrchief 的回答。显然,他们现在已将其添加到文档中。

于 2011-08-24T16:54:40.257 回答
0

这应该更好

$(element).find('.x:first');
于 2011-08-24T16:47:07.397 回答
0

使用:first选择器:

$(element).find('.x:first')
于 2011-08-24T16:47:19.623 回答
0

最好写:

$('a:first');

你写的是“在'元素'中,找到'.x'并返回第一个”。可以这样表达

$('.x:first', element);
于 2011-08-24T16:47:42.773 回答
0

使用first-child伪类怎么样?像

$(element).find('.x:first-child')

但是,如果您的结构像

<div>
   <p></p>
</div>
<div>
   <p></p>
</div>

所以实际上这不是您要寻找的(如果您的意思是通用解决方案)。其他人:首先,这似乎是正确的方法

于 2011-08-24T16:47:46.663 回答
0

您的瓶颈实际上是.find(),它搜索所有后代,而不仅仅是直系孩子。

最重要的是,您正在搜索一个类.x(使用 jQuery 自定义搜索)而不是 ID 或标记名(使用本机 DOM 方法)。

我会使用 Mrchief 的答案,然后,如果可能的话,修复这两个瓶颈以加快您的选择器。

于 2011-08-24T16:51:39.700 回答
0

根据 jQuery 文档,这种方式很好,或者至少比使用:first选择器更好。

您可以尝试作为替代方案.filter(":first"),或者使用数组访问器获取第一个.find()元素[0]

此外,.find()您可以将其更改为:

$('.x', element)

将搜索范围缩小到.x元素内的元素,而不是搜索整个文档。

于 2011-08-24T16:53:45.957 回答
0

您可以使用后代选择器组合$(element)and调用;.find()我不确定性能比较:

$("#element .x").first().hide();
于 2011-08-24T16:55:21.320 回答