JQuery在if语句中检查是否具有多个类名

87

我有一个简单的if语句,如下所示:

if ($('html').hasClass('m320')) {

// do stuff 

}

这个代码可以正常运行。然而,我想要在if语句中添加更多的类来检查是否有任何一个类存在于<html>标签中。我需要这样做是为了不是所有的类都被检查,而只是至少存在一个类但也可以是多个。
我的使用情况是,我为各个视口宽度添加了类(例如m320m768),所以我只想在特定宽度(类)下执行特定的Jquery。
以下是我尝试过的内容:
1.
if ($('html').hasClass('m320', 'm768')) {

// do stuff 

}

2.

if ($('html').hasClass('m320')) || ($('html').hasClass('m768')) {

 // do stuff 

}

3.

 if ($('html').hasClass(['m320', 'm768'])) {

 // do stuff 

    }

然而,这些方法似乎都不起作用。我不确定自己做错了什么,但很可能是语法或结构的问题。


1
不要猜测API的工作方式,应该阅读文档。http://api.jquery.com/hasclass/ 另外,在开发过程中,你应该随时准备好/打开开发者控制台。 - cliffs of insanity
可能是重复的问题:jQuery hasClass() - check for more than one class - Stephan Weinhold
10个回答

174
你可以使用is()代替hasClass():
if ($('html').is('.m320, .m768')) { ... }

3
hasClass() 可能更快,但大多数情况下 is() 更方便。 - elclanrs
1
顺便提一下,在这里我们可以看到is()hasClass()的性能基准。 - Jignesh Gohel
1
所以它的速度要慢得多,但整体上也非常快。如果只有几个项目被扫描,似乎对于更干净的代码来说并不是什么大问题。 - jerclarke
1
信息: "is" 匹配类 a 或 b,"hasClass" 匹配类 a 和 b。 - NinoMarconi

77

你在第二次尝试中只是括号混乱了。

var $html = $("html");

if ($html.hasClass('m320') || $html.hasClass('m768')) {

  // do stuff 

}

7
你真的应该将 $('html') 缓存到一个变量中,而不是多次查找它。 - epascarello
2
@epascarello非常正确,为了后人更新答案。 - James Montagne

31

出于兴趣,我编写了一个小的jQuery附加方法,用于检查任意一个多个class名称:

$.fn.hasAnyClass = function() {
    for (var i = 0; i < arguments.length; i++) {
        if (this.hasClass(arguments[i])) {
            return true;
        }
    }
    return false;
}

那么,在您的例子中,您可以使用以下代码:

if ($('html').hasAnyClass('m320', 'm768')) {

// do stuff 

}

你可以传递任意数量的类名。


以下是增强版,还允许你通过空格分隔多个类名:

$.fn.hasAnyClass = function() {
    for (var i = 0; i < arguments.length; i++) {
        var classes = arguments[i].split(" ");
        for (var j = 0; j < classes.length; j++) {
            if (this.hasClass(classes[j])) {
                return true;
            }
        }
    }
    return false;
}

if ($('html').hasAnyClass('m320 m768')) {
    // do stuff 
}

工作演示: http://jsfiddle.net/jfriend00/uvtSA/


很好,这个运行良好...而且跨浏览器也没问题!在FF和IE上测试过。 - crmpicco
我进行了一些轻微的修改,使其符合jQuery的.addClass和.removeClass()约定。 (https://dev59.com/MGkv5IYBdhLWcg3wfA4P#14887517) - CyberMonk

28

这可能是另一种解决方案:

if ($('html').attr('class').match(/m320|m768/)) {  
  // do stuff   
}  
根据 jsperf.com 的测试结果,这个方法非常快速。

非常好,速度快多了! - Philip
9
这也将匹配类似于 'ZZZm320WWW' 的类。请尝试使用...match(/\b(m320|m768)\b/),其中 \b 匹配单词的开头和结尾。 - Juan Lanus
只是跟进一下(7年后 :))。这个方法很好用,但如果你定义的HTML元素没有任何类 - 它会报一个“无法读取未定义属性'match'”的错误。如果是这种情况,请测试该元素是否具有'class'属性(或测试以确保属性'class'不为null)。 - Sanya

6
对于那些想了解所有不同选项的性能方面的人,我在这里创建了一个jsperf案例:jsperf
简而言之,使用element.hasClass('class')是最快的。
下一个最好的选择是使用elem.hasClass('classA') || elem.hasClass('classB')。关于这个问题需要注意的是:顺序很重要!如果更有可能找到类“classA”,请先列出它!OR条件语句会在满足其中一个条件时立即返回。
迄今为止最差的性能是使用element.is('.class')
在jsperf中还列出了CyberMonk的函数Kolja的解决方案

真的很有趣!我不知道jsperf。感谢您说明所有不同的变化。 - Danny Englander

3

这里是对jfriend00所提供答案的略微变化:

$.fn.hasAnyClass = function() {
    var classes = arguments[0].split(" ");
    for (var i = 0; i < classes.length; i++) {
        if (this.hasClass(classes[i])) {
            return true;
        }
    }
    return false;
}

这个方法允许使用与 .addClass() 和 .removeClass() 相同的语法,例如:.hasAnyClass('m320 m768')。当然,需要进行防错处理,因为它假设至少有一个参数。


0

如果您需要同时存在两个类,请使用此方法。如果只需要其中一个逻辑,则可以使用||。

$('el').hasClass('first-class') || $('el').hasClass('second-class')

随意进行必要的优化


1
这是错误的。你给出的第一个例子之所以能够工作,只是因为该方法对输入进行了较差的净化,并认为整个字符串是一个类名。如果类的顺序不同或者它们不紧挨着彼此,它就无法工作。请参见示例:https://jsfiddle.net/0d57ekty/ - MightyPork
@MightyPork 感谢您的检查。您是正确的,它应该仅在每个类中使用。 - qwerty_igor

0
hasClass方法将接受一个类名数组作为参数,您可以像这样操作:
$(document).ready(function() {
function filterFilesList() {
    var rows = $('.file-row');
    var checked = $("#filterControls :checkbox:checked");

    if (checked.length) {
        var criteriaCollection = [];

        checked.each(function() {
            criteriaCollection.push($(this).val());
        });

        rows.each(function() {
            var row = $(this);
            var rowMatch = row.hasClass(criteriaCollection);

            if (rowMatch) {
                row.show();
            } else {
                row.hide(200);
            }
        });
    } else {
        rows.each(function() {
            $(this).show();
        });
    }
}

    $("#filterControls :checkbox").click(filterFilesList);
    filterFilesList();
});

0
var classes = $('html')[0].className;

if (classes.indexOf('m320') != -1 || classes.indexOf('m768') != -1) {
    //do something
}

2
如果你要这样做,为什么还要使用jQuery来获取元素呢? - James Montagne
我本不想这样,但至少它只获取一次类?没有一点jQuery,看起来就显得很乏味,所以我用一些jQ特殊技巧替换了getElementsByTagName,专门为你做了这个! - adeneo

-1

试试这个:

if ($('html').hasClass('class1 class2')) {

// do stuff 

}

欢迎来到 Stack Overflow!请添加一些解释,说明这段代码为什么能帮助 OP。这将有助于提供一个让未来的观众可以学习的答案。请参见 [answer] 获取更多信息。 - Heretic Monkey

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