4

我有以下代码:

$( '#parent' ).on( 'click', '.a .b .c,.a .b .d,.a .b .e', function(){ ... });

三个选择器,要清楚的是:

.a .b .c
.a .b .d
.a .b .e

我试图弄清楚是否有可能以某种方式减少它:

.a .b (.c,.d,.e)

而且我知道如何轻松地使用非实时查询(例如使用.find),但我特别希望将此事件附加到$( '#parent' )

4

6 回答 6

2

如果有人想使用它,请从 OP 进行编辑:阅读下面我的评论中的警告

这是你要找的吗?http://forum.jquery.com/topic/feature-req-any-selector-filter

jQuery.expr[':'].any = function(el, i, match) {
    return jQuery.find.matches(match[3], [el]).length > 0;
};
于 2013-02-08T01:54:02.793 回答
1

我不确定这是否可能,但我会尝试使用一些正则表达式来发挥创意:

$('#parent').on('click', 'c,d,e'.replace(/(\w+)/g, '.a.b.$1')

这个想法是事先创建选择器。

于 2013-02-08T01:37:08.637 回答
1

如果您可以控制类名是什么,则可以使用命名约定。而不是 .c、.d、.e 等,将它们命名为 .cd、.ce、.cf 等。然后您可以[class^="c-"]用作选择器。

更具体地编辑:

$( '#parent' ).on( 'click', '.a .b [class|="c"] ...
于 2013-02-08T01:46:04.573 回答
1

感谢Felix,我自己回答了这个问题:

jQuery.expr[':'].matches = function( elem, index, match ){
    return $( elem ).is( match[3] );
};

$( '#parent' ).on( 'click', '.a .b :matches( .c, .d, .e )', ... );

出于性能原因,应该稍微优化一下:

.a .b nodeTypeOrOtherSelector:matches( .c, .d, .e )
于 2013-02-08T01:53:15.487 回答
0

稍微简化选择器的一种方法是将.a .b测试移动到回调中:

$( '#parent' ).on('click', '.c, .d, .e', function(){
    if ($(this).closest('.a .b').length === 0) {
        // not the right element
        return;
    }
    // ...
});

但从性能或代码维护的角度来看,这是否是可取的,我不知道。

学习elclanrs的解决方案,您可以动态创建选择器:

var ancestors = '.a .b';
var selector = ancestors + ['.c', '.d', '.e'].join(', ' + ancestors);

除此之外,您无能为力。CSS 选择器不能以这种方式工作。

于 2013-02-08T01:37:41.510 回答
0

为什么不将公共.a .b祖先选择器移动到目标上下文选择器中?这应该有效:

$('#parent .a .b').on('click', '.c, .d, .e', function(){ ... });

更新: @cwolves 正确地指出,这只适用于静态,.a .b即在附加处理程序时出现在页面上,这首先违背了委托事件的目的。

于 2013-02-08T01:42:02.017 回答