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

时间:2012-07-24 04:50:00

标签: javascript jquery jquery-selectors

供参考,这是一篇关于Creating a Custom Filter Selector with jQuery的文章。


简介:

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

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

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

  1. 有问题的元素

  2. 整个集合

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

  5. 扩展jQuery.expr[':']后,您可以将其用作jQuery选择器中的过滤器,就像使用任何内置的过滤器一样(:first:last:eq()等。)


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

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

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


    在上面的例子中,我们没有使用传递给我们函数的match数组。让我们尝试一个更复杂的例子。在这里,我们将创建一个过滤器,以匹配比指定数字tabindex更高的元素:

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

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

    这样做的原因是因为match数组是从用于解析选择器的正则表达式返回的实际数组。因此,在我们的示例中,match would be the following array

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

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


    问题:

    在jQuery 1.8中,the match array is no longer being passed in to the filter function。由于我们无法访问传入的信息,the tabindexAbove filter does not work anymore(这个小提琴和上面的一个之间的唯一区别在于它使用了更高版本的jQuery)。

    所以,我想澄清几点:

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

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

    3. 既然我们无法访问match数组,是否有其他方法可以获取传递给过滤器的信息(在我们的例子中,4)?< / p>

    4. I never found any documentation in the jQuery Docs about the custom filter selectors,所以我不知道从哪里开始寻找有关此事的信息。

2 个答案:

答案 0 :(得分: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');

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

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

答案 1 :(得分:7)

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

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

这是jsfiddle上的working example

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

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;