使用jQuery选择具有多个类的元素

3

我需要选择包含多个类的所有元素。不需要考虑类名,只需选择具有两个或更多类的任何元素。

那么这个 jQuery 选择器是什么样子?


类似但仅使用纯CSS:如何使用CSS来针对任何具有任意两个类的元素进行定位?(我的答案也可以作为jQuery选择器) - BoltClock
5个回答

8

这应该选择具有两个以上类的 所有 元素。

$('*').filter(function() {
  return this.className.trim().split(/\s+/).length > 1;
}).foo('bar');

1
没想到你会这么做,很聪明。因为你展示了不同的解释,所以我给你点赞。 - Brad Christie
不是要刻意挑毛病,但这并不是正确的解决方案,因为具有单个类但类属性中有一些空格的元素也可能被错误地选择,就像我在我的答案中解释的那样。这里有一个例子:http://jsfiddle.net/udBZy/3/ 此外,$('*')是不必要的低效率。 - maxedison
@maxedison:谢谢,我实际上没有运行代码。至于效率,你甚至可以定义一个比 * 更具体的范围。我只是选择了最广泛的范围。 - Blender
为什么在使用.split()时要使用正则表达式? - maxedison
如果只按单个空格分割,"foo[space][space]bar" 将被分成三个部分:"foo"、"" 和 "bar"。正则表达式的作用是清除任何连续的空格。 - BoltClock

3
$('[class*=" "]')

返回所有class属性中带有空格的标签。

1
这将匹配<div class="foo"> - BoltClock
这种情况很常见,特别是在 ERB/JSP/其他编译 HTML 模板中生成类时。如果要使用正则表达式,我认为你需要升级到 Blender 的解决方案。 - Elliot Nelson

2
一个不同的理解会带来更好的解决方案(抱歉我之前下了个结论):
演示: Demo
(function($){
    $.expr[':'].classes = function(o,i,m,s){
        var c = o.className.match(/\s*(.*)\s*/)[0].split(/\s+/).length;

        // Hard [fixed] limit
        // :classes(N)
        if (/^\d+$/.test(m[3])) {
            var n = parseInt(m[3], 10);
            return o.className.split(/\s+/).length == n;
        }

        // Expression:
        // :classes(>N)    :classes(>=N)
        // :classes(>N)    :classes(<=N)
        else if (/^[<>]=?\d+$/.test(m[3])) {
            var e = m[3].match(/^[><]=?/)[0],
                n = m[3].match(/\d+$/)[0];
            switch (e){
                case '<':
                    return c < n;
                case '<=':
                    return c <= n;
                case '>':
                    return c > n;
                case '>=':
                    return c >= n;
            }
        }

        // Range
        // :classes(4-6)
        else if (/^\d+\-\d+$/.test(m[3])) {
            var ln = parseInt(m[3].match(/^(\d+)/)[0], 10),
                hn = parseInt(m[3].match(/(\d+)$/)[0], 10);
            return ln <= c && c <= hn;
        }

        // all else fails
        return false;
    };
})(jQuery);

更新:现在您可以提供以下选项(将N和M替换为数字),从而增加了一些关于参数的灵活性:

  • :classes(N)
    查找具有完全N个类的元素
  • :classes(<=N)
    查找具有N个或更少类的元素
  • :classes(<N)
    查找具有少于N个类的元素
  • :classes(>=N)
    查找具有N个或更多类的元素
  • :classes(>N)
    查找具有多于N个类的元素
  • :classes(N-M)
    查找类计数介于N和M之间的元素

但这需要您知道类的名称。 - JonH
@JonH:更新了一个更好的解决方案。;-) - Brad Christie

1
以下代码将首先选择所有在类属性中带有空格的元素。我们可以像Blender建议的那样使用$('*'),但这样效率较低,因为它最初选择页面上的所有元素,而不仅仅是那些可行的候选元素(即类名中带有空格的元素)。
它还考虑了只有一个类,但类属性中有空格的情况(这是通过在分割之前使用jQuery的$.trim()方法处理类属性来完成的)。Blender并不能解决这种情况。
$(function(){
    var div = $('div[class*=" "]').filter(function(){
        var clsArray = $.trim(this.className.split(' ');
        return clsArray.length > 1;
    });
    div.css('background','yellow');
});

实时示例:http://jsfiddle.net/udBZy/3/


0

它的工作方式就像普通的CSS一样

$('.class1.class2') // will select elements with both classes

1
这需要您事先了解类,并且它仅选择具有多个类的特定元素。 - BoltClock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接