在jQuery中,我可以使用函数而不是CSS选择器吗?

时间:2014-10-04 17:23:22

标签: javascript jquery css-selectors fluent-interface

而不是使用$('.list').find('li:not(.done):last'),它返回的所有LI不是.done,而是每个.list的最后一个,我怎样才能使用函数?

例如,$('.list').find('li').not('.done').last()只会返回一个项目,因为它会搜索所有.list LI的非.done,然后只返回最后一个。< / p>

我想做这件事有几个原因。首先,通常使用函数比CSS选择器更快(在某些情况下,特别是当你将它们分成多个函数时,因为jQuery不必手动拆分选择器,并且jQuery函数通常只是直接映射到现有的CSS选择器) )。但无论如何,好奇心是我目前的主要原因,而且表现是次要的。

示例代码(不完全代表实际代码,但结构类似):

<ul class="list">
  <li>One</li>
  <li class="done">Two</li>
</ul>

<ul class="list">
  <li class="done">Three</li>
  <li>Four</li>
</ul>

我想返回以下节点:

OneFour

3 个答案:

答案 0 :(得分:1)

我没有提出一种不需要循环的方法,例如:

$(".list").map(function() {
  var items = $(this).find("li").not(".done");
  return items[items.length - 1];
});

&#13;
&#13;
// Old way
$(".list").find("li:not(.done):last").css("color", "red");

// Just to show it's wrong (as the question says)
$(".list").find("li").not(".done").last().css("background-color", "yellow");

// Alternative
$(".list").map(function() {
  var items = $(this).find("li").not(".done");
  return items[items.length - 1];
}).css("border", "1px solid black");
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="list">
  <li>One</li>
  <li>Two</li>
  <li class="done">Three (done)</li>
</ul>
<ul class="list">
  <li>One</li>
  <li>Two</li>
  <li class="done">Three (done)</li>
</ul>
&#13;
&#13;
&#13;


您可能认为使用选择器的原因较慢的是像:last这样的选择器是jQuery扩展,而不是真正的CSS选择器,这意味着Sizzle(jQuery的选择器引擎)必须在JavaScript中处理它们,而不是而不是将它们卸载到浏览器内置的(更快)选择器引擎。如果您将自己局限于浏览器实现的CSS选择器,通常选择器将获胜(以其他因为模数,以及YMMV)。我无法解释你的看似是因为:not(.done)(这是一个有效的CSS选择器)而改变了DOM,除非Sizzle做了一些它真的不应该处理它(因为Sizzle支持复杂) :not内的选择器,而CSS没有。

答案 1 :(得分:0)

你实际上并不需要一个功能。以下任何选择器都将返回OneFour的节点:

  • $('.list li:not(.done)')
  • $('.list li').not('.done')
  • $('li:not(.done)')

使用$('.list li:last-child').not('.done')会返回最后一个孩子不具有done班级(Four)的项目。

那就是说,如果你真的想要使用一个函数,你可以使用jQuery的.contents().filter()方法。

$('.list').contents().filter( function(i,v){
  if( v.nodeType === 1 && !$(v).hasClass('done') ){
    return v; // Returns 'One' and 'Four'
  }
});

以上所有a fiddle

答案 2 :(得分:0)

  

我想做这件事有几个原因。首先,通常使用函数比CSS选择器更快   有我不想要的LI,我希望每个列表的最后一个不匹配类

最快的方法是XPath,因为它是原生的:

//*[@class='list']/li[@class!='done']/*[last()]
  

但无论如何,好奇心是我目前的主要原因,而且表现是次要的。

jQuery 1.0支持XPath,然后切换到最终成为Sizzle的选择器引擎:

  

最近,我一直在为XPath和CSS 3构建解析器做了很多工作 - 我很惊讶它们在某些方面有多么相似 - 但在其他方面完全不同。例如,CSS被完全调整为与HTML一起使用,使用#id(通过ID获取内容)和.class(通过其类获取某些内容)。另一方面,XPath必须能够使用..遍历DOM树并使用foo [bar]测试存在(foo有一个bar元素子)。最重要的事情是,与XPath相比,CSS选择器通常非常短 - 但是功能不足。

在1.2中删除了

  

由于在1.2中从jQuery中删除了XPath选择器,因此引入了新的XPath Selector Plugin。您可以使用此插件为自己创建自创建以来在jQuery中存在的CSS / XPath混合选择器。

DOM遍历技术包括:

  

Tree Walker

使用DOM Level 2 Tree Walker方法的实现。构建通用过滤器函数并遍历所有元素。

  

的XPath

构建单个表达式并让XPath引擎遍历文档,找到所有相关元素。

  

混合

混合XPath和DOM实现;尽可能使用XPath。

<强>参考