【问题标题】:Getting the "match" object in a Custom Filter Selector in jQuery 1.8在 jQuery 1.8 的自定义过滤器选择器中获取“匹配”对象
【发布时间】:2012-07-22 09:16:07
【问题描述】:

供参考,这里有一篇关于Creating a Custom Filter Selector with 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');

这是小提琴: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)吗?

I never found any documentation in the jQuery Docs about the custom filter selectors,所以我不知道从哪里开始寻找这方面的信息。

【问题讨论】:

    标签: javascript jquery jquery-selectors


    【解决方案1】:

    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

    【讨论】:

    • +1 获取文档链接。接受createPseudo 工厂。
    【解决方案2】:

    通过查看 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;
    

    【讨论】:

    • +1 好答案!谢谢。遗憾的是,新的做法更加冗长。 (顺便说一句,you can see all the Sizzle aliases here)。出于某种原因,我仍然没有完全理解他们用来编译选择器函数的方法。你知道有什么资料可以更详细地解释这一点吗?
    • 谢谢。我进行了快速搜索,但不幸的是,除了博客文章和源代码之外,我没有找到任何特别有用的东西。让我试着找一个;否则我们可能需要深入挖掘源代码。
    • 恐怕是这样。我翻遍了源代码,但仍然没有得到全貌;我想我必须再花一点时间才能完全理解这一切。再次感谢您的精彩回答!
    猜你喜欢
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 2011-12-10
    • 2011-02-22
    • 1970-01-01
    相关资源
    最近更新 更多