在jQuery 1.8中的自定义筛选器选择器中获取“匹配”对象

作为参考,这里有一篇关于使用jQuery创建自定义filter选择器的文章。


介绍:

对于那些不熟悉jQuery的自定义滤波器选择器的人 ,这里有一个关于它们的快速入门:

如果需要可重用的filter ,可以通过将自己的函数添加到jQuery.expr[':']对象来扩展jQuery的选择器表达式。

该函数将在当前集合中的每个元素上运行,并应返回true或false(非常类似于filter )。 三位信息传递给此函数:

  1. 有问题的元素

  2. 整个集合中此元素的索引

  3. 从正则表达式匹配返回的match数组,其中包含更复杂表达式的重要信息。

一旦你扩展了jQuery.expr[':'] ,就可以在jQuery选择器中使用它作为filter,就像你使用任何内置的filter一样( :first:last:eq()等。)


这是一个示例,我们将过滤分配了多个类的元素:

 jQuery.expr[':'].hasMultipleClasses = function(elem, index, match) { return elem.className.split(' ').length > 1; }; $('div:hasMultipleClasses'); 

这是小提琴: http : //jsfiddle.net/acTeJ/


在上面的例子中,我们没有使用传入我们函数的match数组。 让我们尝试一个更复杂的例子。 在这里,我们将创建一个filter,以匹配tabindex高于指定数量的元素:

 jQuery.expr[':'].tabindexAbove = function(elem, index, match) { return +elem.getAttribute('tabindex') > match[3]; }; $('input:tabindexAbove(4)'); 

这是小提琴: http : //jsfiddle.net/YCsCm/

这样做的原因是因为match数组是从用于解析选择器的正则表达式返回的实际数组。 所以在我们的例子中, match将是以下数组 :

 [":tabIndexAbove(4)", "tabIndexAbove", "", "4"] 

如您所见,我们可以使用match[3]获得括号内的值。


问题:

在jQuery 1.8中, match数组不再被传递给filter函数 。 由于我们无法访问传入的信息, 因此tabindexAbovefilter不再起作用 (这个小提琴和上面的一个之间的唯一区别是,它使用更高版本的jQuery)。

所以,我想澄清几点:

  1. 这是预期的行为吗? 是否记录在任何地方?

  2. 这与Sizzle更新事实有什么关系(尽管它明确指出“在重写中没有改变Sizzle的旧API”。也许这就是他们所说的“删除现在不必要的Sizzle.filter “)?

  3. 现在我们无法访问match数组,有没有其他方法可以获取传递给filter的信息(在我们的例子中, 4 )?

我从未在jQuery Docs中找到有关自定义filter选择器的任何文档 ,因此我不知道从哪里开始查找有关此内容的信息。

jQuery添加了一个用于在Sizzle中创建自定义伪的实用程序。 它有点冗长,但它比使用match [3]更具可读性。 它还具有更高性能的优点,因为每次测试元素时都可以避免重复繁琐的计算。 已经接受的答案是一个很好的答案,但是让我添加一个注释,说你可以使用$ .expr.createPseudo而不是自己设置sizzleFilter属性,这将节省一点空间。

 jQuery.expr[':'].tabIndexAbove = $.expr.createPseudo(function( tabindex ) { return function(elem) { return +elem.getAttribute('tabindex') > tabindex; } }); $('input:tabIndexAbove(4)').css('background', 'teal'); 

jsfiddle: http : //jsfiddle.net/timmywil/YCsCm/7/

这些都记录在Sizzle的github上: https : //github.com/jquery/sizzle/wiki/Sizzle-Documentation

通过查看jQuery 1.8 beta2源代码和The New Sizzle的“Extensibility”部分,您必须将fn.sizzleFilter设置为true才能获得伪参数和上下文。 如果没有,您将获得参数中的所有元素。

这是与您的示例完成相同操作的代码。 使用函数中传递的selector参数来获取伪参数。

这是关于jsfiddle的工作示例 。

正如上面的博客文章中提到的,您甚至可以预编译和缓存选择器。

 var sizzle = jQuery.find; var tabIndexAbove = function( selector, context, isXml ) { return function( elem ) { return elem.getAttribute("tabindex") > selector; }; }; /* fn.sizzleFilter is set to true to indicate that tabIndexAbove is a function that will return a function for use by the compiler and should be passed the pseudo argument, the context, and whether or not the current context is xml. If this property is not set, adding pseudos works similar to past versions of Sizzle */ tabIndexAbove.sizzleFilter = true; sizzle.selectors.pseudos.tabIndexAbove = tabIndexAbove; $('input:tabIndexAbove(4)').css('background', 'teal'); 

请注意,如果您正在查看源代码,jQuery稍微改变了面向公众的接口所指向的结构。

在jQuery 1.7.2中:

 jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; jQuery.expr[":"] = jQuery.expr.filters; 

在jQuery 1.8b2中:

 jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; jQuery.expr[":"] = jQuery.expr.pseudos;