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, який ви визначаєте, немає класів - він видасть помилку "Не вдається прочитати властивість" збіг "невизначеного". Якщо це так, перевірте, чи має елемент навіть атрибут 'class' (або перевірте, щоб атрибут 'class' не був нульовим).
Санья

5

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

Словом, використання element.hasClass('class')є найшвидшим.

Наступною найкращою ставкою є використання elem.hasClass('classA') || elem.hasClass('classB'). Примітка щодо цього: порядок має значення! Якщо найімовірніше буде знайдений клас 'classA', перелічіть його спочатку! АБО умови умови повертаються, як тільки один із них виконується.

Найгіршою продуктивністю на сьогоднішній день було використання element.is('.class').

У jsperf також вказана функція CyberMonk та рішення Колі .


Дійсно цікаво! Я не мав уявлення про 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
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! Будь ласка, додайте пояснення, чому цей код допомагає операційній програмі. Це допоможе дати відповідь, на якій можуть повчитися майбутні глядачі. Докладніше див. У розділі Як відповісти .
Єретична мавпа
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.