Перевірте, чи вже призначений клас перед додаванням


113

У jQuery рекомендується перевірити, чи клас вже призначений елементу перед тим, як додати цей клас? Чи матиме це взагалі якийсь ефект?

Наприклад:

<label class='foo'>bar</label>

Якщо ви сумніваєтесь у тому, що клас bazвже призначений label, чи це найкращий підхід:

var class = 'baz';
if (!$('label').hasClass(class)) {
  $('label').addClass(class);
}

або цього буде достатньо:

$('label').addClass('baz');

12
Я використовував .hasClassлише тоді, коли мені потрібно перевірити, чи існує клас, якщо мені просто потрібно призначити клас - я використовую .addClass. jQuery не дублює класи
Samich

7
Просто додайте клас без тестування. Якщо вона вже існує, вона більше не буде додана.
Blazemonger

Відповіді:


177

Просто зателефонуйте addClass(). jQuery зробить перевірку за вас. Якщо ви перевірите самостійно, ви подвоюєте роботу, оскільки jQuery все одно запустить вам чек.


47

Проста перевірка на консолі сказала б вам, що дзвонити addClassкілька разів із одним класом безпечно.

Зокрема, ви можете знайти чек у джерелі

if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
  setClass += classNames[ c ] + " ";
}

2
Будь ласка, перечитайте моє запитання, і ви помітите, що мова йде не про безпечну безпеку, а про найкращу практику
Muleskinner

7
З вашої відредагованої відповіді я бачу, що jQuery насправді перевіряє, чи присвоєно клас все-таки перед тим, як додати його, тобто було б поганою практикою робити перевірку самостійно / дякую
Muleskinner

5
@Muleskinner це те, що я мав на увазі.
Райнос

41
@Raynos: Проста перевірка в консолі сказала б вам, що викликати addClass кілька разів із одним класом є безпечним. І все-таки це запитання було одним з найкращих хітів, коли я гуглив за відповідь ... Навіть тривіальні речі, які добре зафіксовані в інших місцях, мають місце в Stack Overflow.
eirirlar

10
У цій відповіді занадто багато ставлення. Могли відповісти на це якоюсь тактовністю.
dreadwail

4

Це питання привернуло мою увагу наступним чином іншого, який був позначений як дублікат цього .

Ця відповідь підсумовує прийняту відповідь з невеликою кількістю доданих деталей.

Ви намагаєтесь оптимізувати, уникаючи зайвої перевірки, у зв'язку з цим ось фактори, які ви повинні знати:

  1. неможливо мати дублікати імен класу в атрибуті класу за допомогою маніпулювання елементом DOM через JavaScript. Якщо у вас є class="collapse"HTML, виклик Element.classList.add("collapse");не додасть додаткового згортання клас . Я не знаю основної реалізації, але я вважаю, що вона повинна бути досить хорошою.
  2. JQuery робить деякі необхідні перевірки в його addClassта removeClassреалізаціях (я перевірив вихідний код ). Тому що addClassпісля деяких перевірок і наявності класу JQuery не намагається його знову додати. Аналогічно removeClass, і JQuery робить щось, у рядку cur.replace( " " + clazz + " ", " " );якого буде видалено клас, лише якщо він існує.

Варто зауважити, JQuery робить певну оптимізацію в його removeClassреалізації, щоб уникнути безглуздого повторного відображення. Виходить так

...
// only assign if different to avoid unneeded rendering.
finalValue = value ? jQuery.trim( cur ) : "";
if ( elem.className !== finalValue ) {
    elem.className = finalValue;
}
...

Таким чином, найкраща мікрооптимізація, яку ви могли б зробити, була б з метою уникнути накладних витрат викликів функцій та відповідних перевірок впровадження.

Скажімо, ви хочете переключити клас з назвою collapse, якщо ви повністю контролюєте, коли клас додається чи видаляється, і якщо collapseклас спочатку відсутній, ви можете оптимізувати наступним чином:

$(document).on("scroll", (function () {
    // hold state with this field
    var collapsed = false;

    return function () {
        var scrollTop, shouldCollapse;

        scrollTop = $(this).scrollTop();
        shouldCollapse = scrollTop > 50;

        if (shouldCollapse && !collapsed) {
            $("nav .branding").addClass("collapse");
            collapsed = true;

            return;
        }

        if (!shouldCollapse && collapsed) {
            $("nav .branding").removeClass("collapse");
            collapsed = false;
        }
    };
})());

Крім того, якщо ви перемикаєте клас через зміни положення прокрутки, вам дуже рекомендується придушити обробку подій прокрутки.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.