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

Jos*_*ber 23 javascript jquery jquery-selectors

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


介绍:

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

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

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

  1. 有问题的元素

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

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

一旦你扩展jQuery.expr[':'],你可以用它在你的jQuery选择过滤器,就像你使用任何内置者的(:first,:last,:eq()等)


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

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

$('div:hasMultipleClasses');
Run Code Online (Sandbox Code Playgroud)

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


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

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

$('input:tabindexAbove(4)');
Run Code Online (Sandbox Code Playgroud)

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

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

[":tabIndexAbove(4)", "tabIndexAbove", "", "4"]
Run Code Online (Sandbox Code Playgroud)

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


问题:

jQuery中1.8,match阵列不再被传递到过滤器功能.由于我们无法访问传入的信息,因此tabindexAbove过滤器不再起作用(这个小提琴和上面的小提琴之间的唯一区别在于它使用了更高版本的jQuery).

所以,这里有几点我要澄清:

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

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

  3. 现在我们无法访问match数组,是否还有其他方法可以将信息传递给过滤器(在我们的例子中4)?

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

小智 10

jQuery添加了一个用于在Sizzle中创建自定义伪的实用程序.它有点冗长,但它比使用匹配更具可读性[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');
Run Code Online (Sandbox Code Playgroud)

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

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


322*_*896 7

通过查看jQuery的1.8β2源的"可扩展性"部分新灒,你必须设置fn.sizzleFiltertrue为了获得伪参数和上下文.如果没有,您将获得参数中的所有元素.

这是与您的示例完成相同操作的代码.使用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');
Run Code Online (Sandbox Code Playgroud)

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

在jQuery 1.7.2中:

jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters;
Run Code Online (Sandbox Code Playgroud)

在jQuery 1.8b2中:

jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos;
Run Code Online (Sandbox Code Playgroud)