【问题标题】:Looking for jQuery find(..) method that includes the current node寻找包含当前节点的 jQuery find(..) 方法
【发布时间】:2010-05-13 15:29:30
【问题描述】:

jQuery find(..) 遍历方法不包括当前节点——它从当前节点的子节点开始。调用在其匹配算法中包含当前节点的查找操作的最佳方法是什么?浏览文档时,没有任何东西会立即跳出来。

【问题讨论】:

    标签: jquery


    【解决方案1】:

    对于 jQuery 1.8 及更高版本,您可以使用.addBack()。它需要一个选择器,因此您不需要过滤结果:

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

    在 jQuery 1.8 之前,您一直使用 .andSelf(),(现已弃用并删除),然后需要过滤:

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

    【讨论】:

    • 我已经将它捆绑为一个插件 jquery.findIncludeSelf,在 bower 注册。见github.com/ronen/jquery.findIncludeSelf
    • @ronen 可以在一行中完成的事情的额外文件?谢谢,但不用了。
    • @prc322 对于将所有 javascript 捆绑到单个文件中的部署,额外的文件不会打扰我。一般来说,即使是简单的事情,我也更喜欢使用(经过测试的)库方法,而不是将我的代码与我发现更难阅读的东西混在一起,这会给错误带来更多可能性。特别是在这种情况下,恕我直言,需要指定'selector' 两次,这使得封装更加可取。 YMMV
    • 好的,所以我可能很厚,但你不必指定'selector' 两次,(如@ronen 所述),你不能只使用object.parent().find('selector')吗? ——话虽如此,我喜欢为你做的 lib 的想法。
    • @circa1983 object.parent().find('selector') 包括object 的兄弟姐妹及其后代。
    【解决方案2】:

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

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

    很遗憾.andSelf() 没有选择器,这很方便。

    【讨论】:

    • 在回答完这个问题api.jquery.com/andSelf/#comment-50124533 之后,您甚至在 jquery 页面上添加了一条评论,这就是彻底性。好的!我做了尽职调查,也“喜欢”了那个。
    • 第二个会慢得令人难以置信。第一个只是很慢。
    • @Tgr - 我不反对,但第一个不应该是那个节目,除非你要处理 非常 大量的元素。如果您不需要链接,则可以肯定地跳过重新过滤这些元素。
    • 有趣的是,closest(..) 包括当前的 DOM 元素并在树上向上,而像 find(..) 等所有向下遍历的方法都与当前元素不匹配。当两个操作一起用于完整的垂直搜索时,就好像 jQuery 团队有目的地实现了这些,以免重叠。
    • 请记住,从 v1.8 开始不推荐使用 .andSelf() 并替换为将选择器作为参数的 .addBack()。见api.jquery.com/addBack
    【解决方案3】:

    定义

    $.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 没有这个内置的。这么多年的发展真的很奇怪。由于 .find() 的工作方式,我的 AJAX 处理程序未应用于某些顶级元素。

    【讨论】:

    • 这是错误的。它添加了所有的“自我”,即使其中只有一个匹配...... -- 这个错误的一个原因是一个糟糕的命名 jQuery 方法......
    • 我试图修复您报告的错误。现在可以正常使用了吗?
    • 大多数其他答案在那里使用filter(),这更有意义。
    【解决方案4】:
    $('selector').find('otherSelector').add($('selector').filter('otherSelector'))
    

    您可以将$('selector') 存储在变量中以加快速度。如果您非常需要,您甚至可以为此编写自定义函数:

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

    【讨论】:

    • 这仅在您 开始 使用选择器时才有效,但情况可能并非如此。另外,不正确,应该是$('selector').find('otherSelector').add($('otherSelector')),你现在拥有的是.andSelf()。最后,.andFind() 不会根据表达式进行过滤,您需要 .add($(this).filter(expr)) :)
    • @Nick Craver:是的,我忘了过滤部分,现在修好了。 $('selector') 是否被其他获取 jQuery 对象的方法替换并不重要(如果这就是您不以选择器开头的意思),add() 可以像 $() 一样处理任何事情。
    • 我的意思是你的$('selector') 可能是$('selector').children('filter').closest('.class').last()...它可能在一个链中,你不知道你要添加的对象是什么,所以通用解决方案应该采取像过滤器一样的前一个对象:)
    • 我还是不明白为什么会有问题。 this 是调用插件的任何 jQuery 对象。它也可能是调用链的结果。
    【解决方案5】:

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

    //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);
    

    【讨论】:

      【解决方案6】:

      如果您希望链接正常工作,请使用下面的 sn-p。

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

      在调用结束函数后,它返回#foo 元素。

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

      如果不定义额外的插件,你就会陷入困境。

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

      【讨论】:

      • 啊,不...如果this 是多个元素this.is() 已经满足如果只有一个匹配。
      【解决方案7】:

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

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

      如果您正在寻找多个元素,您可以使用:

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

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

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

      【讨论】:

        【解决方案8】:

        我知道这是一个老问题,但有一个更正确的方法。如果顺序很重要,例如当您匹配 :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);
        };
        

        无论如何它不会有效率,但这是我想出的最好的维持正确秩序的方法。

        【讨论】:

          【解决方案9】:

          我认为andSelf 是你想要的:

          obj.find(selector).andSelf()
          

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

          【讨论】:

            【解决方案10】:

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

            $(html).filter('selector')
            

            【讨论】:

              【解决方案11】:

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

              这个小小的 jQuery 扩展做到了:

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

              它结合了find()(仅后代)和filter()(仅当前集)并支持两者都吃的任何参数。 pushStack() 允许 .end() 按预期工作。

              这样使用:

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

              【讨论】:

                【解决方案12】:

                这是正确(但可悲)的事实:

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

                http://jsfiddle.net/SergeJcqmn/MeQb8/2/

                【讨论】:

                • 但是,不适用于分离的节点(以及文档本身)。
                • 呃,不,这将在所有情况下从集合中删除 $(selector) 本身。
                猜你喜欢
                • 1970-01-01
                • 2012-11-27
                • 1970-01-01
                • 1970-01-01
                • 2012-06-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-07-24
                相关资源
                最近更新 更多