Javascript 如何优化$.find().first()?

Javascript 如何优化$.find().first()?,javascript,jquery,optimization,find,findfirst,Javascript,Jquery,Optimization,Find,Findfirst,我需要检索第一个元素 我用这个代码做这个 $(element).find('.x').first(); 据我所知,那个代码 从与.x匹配的元素中检索所有元素 删除不需要的元素 有没有更好的办法?像$.findOne()或其他什么?这样应该更好 $(element).find('.x:first'); 使用:第一个选择器: $(element).find('.x:first') 最好写下: $('a:first'); 你写的是“在‘element’中,找到“.x”并返回第一个”。这可以这样

我需要检索第一个元素

我用这个代码做这个

$(element).find('.x').first();
据我所知,那个代码

  • 从与
    .x
    匹配的
    元素中检索所有元素
  • 删除不需要的元素 有没有更好的办法?像
    $.findOne()
    或其他什么?

    这样应该更好

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

    使用
    :第一个
    选择器:

    $(element).find('.x:first')
    
    最好写下:

    $('a:first');
    
    你写的是“在‘element’中,找到“.x”并返回第一个”。这可以这样表达

    $('.x:first', element);
    
    使用伪类怎么样?像

    $(element).find('.x:first-child')
    
    但是,如果您的结构是

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

    所以事实上,这不是你想要的(如果你指的是一般的解决方案)。其他注释:首先,根据jQuery文档,这似乎是正确的方法:

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

    因此,将选择器重写为:

    $(element).find('.x').filter(":first")
    
    或者(这一个将只给您直接的后代,并且将比
    .find
    更快,除非您也在查找嵌套元素)

    应该会给你更好的结果


    在和提供有价值的输入后更新(见评论), 这两种方法似乎比
    .filter(':first')
    更快,这与doc声称的相反

    $(element).find('.x').first();   // faster
    
    $($(element).find('.x')[0]);     // fastest
    

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

    除此之外,您正在搜索类
    .x
    (使用jQuery自定义搜索),而不是ID或标记名(使用本机DOM方法)


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

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

    您可以尝试作为备选方案
    .filter(“:first”)
    或使用数组访问器针对
    .find()
    结果
    [0]
    获取第一个元素

    此外,您可以将其更改为,而不是
    .find()

    $('.x', element)
    

    要将搜索范围缩小到元素内的
    .x
    元素,必须搜索整个文档。

    在我所看到的每个性能测试中,
    .first()
    :first
    具有更好的性能

    正如大多数人所建议的,似乎使用
    $(element).find(“.x:first”)
    应该有更好的性能。然而,在现实中,
    。first
    更快。我还没有研究jquery的内部结构来找出原因

    显然,使用
    [0]
    然后在jquery对象中重写是最快的:

    $($(元素).find(“.x”)[0])


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

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

    $("#element .x").first().hide();
    

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

    这种用法有点有限,因为只有当
    元素
    是单个元素并且选择器是有效的CSS选择器时,它才会起作用。你可以用它制作一个插件。但是,如果你考虑所有的情况,比如多个元素等等,那就再也没有优势了。 所以,同样,如果您有一个非常特定的用例,这可能是有用的,如果没有,请坚持使用jQuery

    更新:结果表明,制作插件的速度更快:

    (函数($){
    $.fn.findOne=函数(选择器){
    试一试{
    变量元素,i=0,l=this.length;
    而(i
    工作原理:

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

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

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

    @Konerak你告诉我。。。我问了一个问题。你需要优化它有什么原因吗?目前需要很长时间吗?我相信这是一个小优化。。。但是如果我有一个好地方去问“怎么做”。。。为什么不优化它?这是一个超小型优化。除非它引起严重的悲伤,否则我一点也不担心:)那可能会返回多个元素。@John:你说得对!我已经更新了我的答案,以解释这种方法的缺点,并强调它可能不是正确的答案。+1,但我将使用
    .first()
    而不是
    .filter(“:first”)
    。我不知道为什么文档建议使用
    过滤器
    。首先
    更快。(
    .first
    对于可读性也有点意义,但这可能只是首选)@kingjiv:
    过滤器
    利用了原生
    queryselectoral()
    ,它提供了性能提升
    first
    是一种简单的老式选择方式,首先获取所有元素,然后返回第一个元素。因此,我猜想,在使用过滤器的情况下,提升来自单步执行,而在使用
    first
    的情况下,提升来自2个或更多步骤。
    $("#element .x").first().hide();
    
    var $result;
    if(element.querySelector) {
        $result = $(element.querySelector('.x'));
    }
    else {
        $result = $(element).find('.x').first();
    }
    
    (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));