找到一次匹配后防止jQuery中的向下遍历

时间:2014-06-20 22:27:49

标签: javascript jquery html css performance

我希望使用一个选择器,一旦发现匹配,它将停止向下移动,同时仍然穿过兄弟姐妹。请考虑以下事项:

<ul>
  <li class='foo'>
    <ul>
      <li  class='bar'>
      </li>
    </ul>
  </li>
  <li class='baz'>
  </li>
</ul>

使用选择器$('ul li')时,jQuery将返回.foo.bar.baz。理想情况下,我想要一个只有.foo.baz的选择器。

我唯一的想法是:

1)遍历备份,查找$(selected).parents('ul ul')作为排除方法

2)一次完成一个孩子的heiarchy,并在找到匹配后停止遍历。

3)使用$ .not()方法排除ul li ul li之类的$('ul li').not('ul li ul li')

所有这些解决方案看起来都不够优雅和缓慢,因为它们需要多次调用jQuery,并且远离本机DOM方法(即document.querySelectorAll)。通常情况下,我只是选择#3并将其称为一天,但我正在开发一个嵌入式系统,其中cpu周期非常宝贵,并且链接jQuery调用可能会导致性能下降。

有什么想法吗?

编辑:给出的示例只是我将要搜索的可能树结构的抽象。用例是在页面上搜索最接近的匹配作为键盘导航库的一部分。由于布局结构不同,我不能指望匹配是直接后代。

5 个答案:

答案 0 :(得分:2)

您的问题的解决方案需要JavaScript,您的第一和第三个想法是我看到您找到答案的地方。

为了澄清,CSS(和jQuery)选择器是从右到左解释的。创建选择器时,最右边的选择器(键选择器)是您匹配的最终选择器。浏览器将找到键选择器,然后向上(/向后)搜索文档,直到找到匹配或耗尽可能的匹配。

目前没有父CSS选择器以另一种方式执行此操作。

以下是获取您使用jQuery寻找行为的方法示例:http://jsbin.com/jazax/2/

如果没有li个父元素,您可以获取ul中包含的所有li,然后执行某些操作。

$("ul li").each(function() {

    var $this = $(this);
    if(!$this.parents("li").length) 
    {
      $this.prepend(":)");
    }

});

你可以

$("ul li").not("li ul li").each(function () {

  var $this = $(this);
  $this.prepend(":)");

});

或者进一步简化以减少jQuery需要匹配的选择器数量:

$("ul li").not("li li").each(function () {

  var $this = $(this);
  $this.prepend("3");

});

最后,这是一个演示性能比较的示例。 http://jsperf.com/downwardtraverseso

答案 1 :(得分:0)

请参见此处:http://jsbin.com/hefeb/1/edit

$(function(){

  $('ul>li').text('yo');



});

答案 2 :(得分:0)

var $items = $('ul').children();

答案 3 :(得分:0)

最好在li上输出类,因此只有一个dom交互:

$('li.important-link') 

并称之为一天。

答案 4 :(得分:0)

纯粹的&#34;赶上所有LI&#34; JS选择器比所有jQuery解决方案快几倍:

var arr = document.querySelectorAll("li");

即使你必须做这样的事情:

var c = arr.length,
    selected = new Array(c);
while (arr[--c]) {
  if (! $(arr[c]).closest("li").length) selected.push(arr[c]);
}

而且,为了捎带@ niko的测试,你会发现它的整体速度提高了2-3倍:http://jsperf.com/downwardtraverseso/3