JQuery .hasClass для нескольких значений в инструкции if


81

У меня есть простой оператор if как таковой:

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

// do stuff 

}

Это работает, как ожидалось. Однако я хочу добавить больше классов, чтобы if statementпроверить, присутствует ли какой-либо из классов в <html>теге. Мне нужно, чтобы не все, а просто наличие хотя бы одного класса, а может быть и больше.

Мой вариант использования состоит в том, что у меня есть классы (например m320, m768), добавленные для различной ширины окна просмотра, поэтому я хочу выполнить определенный 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, вам следует прочитать документацию. api.jquery.com/hasclass Кроме того, консоль разработчика должна быть под рукой / открыта во время разработки.
скалы безумия

Ответы:


74

Во второй попытке у вас только что были неправильные скобки.

var $html = $("html");

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

  // do stuff 

}

6
Вам действительно следует кэшировать $('html')переменную вместо того, чтобы искать ее несколько раз.
epascarello

1
@epascarello Совершенно верно, обновляя ответ для потомков.
Джеймс Монтань

163

Вы можете использовать is()вместо hasClass():

if ($('html').is('.m320, .m768')) { ... }

3
Да hasClass(), вероятно, быстрее, но в is()большинстве случаев намного удобнее
elclanrs

1
Кстати, здесь мы можем увидеть тесты производительности is()иhasClass()
Jignesh Gohel

1
Так что он намного медленнее, но в целом очень быстрый. Если сканируется всего несколько элементов, это не имеет большого значения для более чистого кода.
jerclarke

28

Ради интереса я написал небольшой дополнительный метод jQuery, который будет проверять одно из нескольких имен классов:

$.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 (). ( stackoverflow.com/a/14887517/170456 )
CyberMonk

25

Это может быть другое решение:

if ($('html').attr('class').match(/m320|m768/)) {  
  // do stuff   
}  

согласно jsperf.com, это тоже довольно быстро.


Очень красиво, намного быстрее!
Филип

9
Это также будет соответствовать классу ZZZm320WWW и подобным. Попробуйте ... match (/ \ b (m320 | m768) \ b /), где \ b соответствуют началу и концу слова.
Хуан Ланус

просто чтобы продолжить (7 лет спустя :)). Это отлично работает, но если элемент html, который вы определяете, не имеет никаких классов, он выдаст ошибку «Невозможно прочитать свойство" соответствует "неопределенному». В этом случае проверьте, есть ли у элемента даже атрибут «класс» (или проверьте, чтобы атрибут «класс» не был нулевым).
Саня

5

Для тех, кто интересуется некоторыми различными аспектами производительности со всеми этими различными параметрами, я создал здесь пример jsperf: jsperf

Короче говоря, используя element.hasClass('class') - самое быстрое.

Следующий лучший вариант - использовать elem.hasClass('classA') || elem.hasClass('classB') . Примечание по этому поводу: порядок имеет значение! Если более вероятно, что будет найден класс classA, сначала укажите его! Операторы условия ИЛИ возвращаются, как только выполняется одно из них.

Наихудшей производительностью было использование element.is('.class').

В jsperf также перечислены функция CyberMonk и решение Коли .


Очень интересно! Я понятия не имел о jsperf. Спасибо за иллюстрации всех вариантов.
Дэнни Энгландер

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
var classes = $('html')[0].className;

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

1
Если вы собираетесь это сделать, зачем вообще использовать jquery для получения элемента?
Джеймс Монтань

Ну, я бы не стал, но, по крайней мере, он получает классы только один раз? Это казалось таким скучным без небольшого количества jQuery, поэтому я заменил getElementsByTagName на некоторую магию jQ специально для вас!
adeneo

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

Это на тот случай, если вам нужны оба класса. Для логики или или просто используйте ||

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

Не стесняйтесь оптимизировать по мере необходимости


1
Это не правильно. Первый приведенный вами пример работает только потому, что метод плохо очищает ввод и считает, что вся строка является именем класса. Это не сработает, если классы расположены в другом порядке или расположены не рядом друг с другом. См. Пример: jsfiddle.net/0d57ekty
MightyPork

@MightyPork, спасибо за проверку. ты прав, его следует использовать только для каждого класса
qwerty_igor

-1

Попробуй это:

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

// do stuff 

}

Добро пожаловать в Stack Overflow! Пожалуйста, объясните, почему этот код помогает OP. Это поможет дать ответ будущим зрителям. См. « Как ответить» для получения дополнительной информации.
Обезьяна-еретик
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.