Проверьте, присвоен ли класс перед добавлением

В jQuery рекомендуется ли проверять, был ли класс уже назначен элементу перед добавлением этого класса? Будет ли это вообще иметь какой-либо эффект?

Например:

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

Если у вас есть сомнения, если класс baz уже назначен label, это лучший подход:

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

или этого будет достаточно:

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

Ответ 1

Просто позвоните addClass(). jQuery проверит вас. Если вы проверите самостоятельно, вы удвоите работу, так как jQuery все равно проведет проверку для вас.

Ответ 2

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

В частности, вы можете найти чек источник

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

Ответ 3

Этот вопрос получил мое внимание после другого, который был отмечен как дубликат этого.

Этот ответ суммирует принятый ответ с небольшими подробностями.

Вы пытаетесь оптимизировать, избегая ненужной проверки, в этом отношении здесь есть факторы, о которых вы должны знать:

  • Невозможно иметь дублирующиеся имена классов в атрибуте class посредством манипулирования элементом DOM с помощью JavaScript. Если у вас есть class="collapse" в вашем HTML, вызов Element.classList.add("collapse"); не добавит дополнительный класс свернуть. Я не знаю основной реализации, но я полагаю, что это должно быть достаточно хорошо.
  • 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;
        }
    };
})());

В стороне, если вы переключите класс из-за изменений в позиции прокрутки, вам настоятельно рекомендуется throttle прокрутка событий.