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

113

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

Например:

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

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

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

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

$('label').addClass('baz');
Muleskinner
источник
12
Я использовал .hasClassтолько тогда, когда мне нужно проверить, существует ли класс, если мне просто нужно назначить класс - я использую .addClass. jQuery не дублирует классы
Самич
7
Просто добавь класс без тестирования. Если он уже существует, он больше не будет добавлен.
Blazemonger

Ответы:

177

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

jmar777
источник
47

Простая проверка в консоли убедила бы вас, что addClassмногократный вызов одного и того же класса безопасен.

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

if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
  setClass += classNames[ c ] + " ";
}
Raynos
источник
2
Пожалуйста, перечитайте мой вопрос, и вы заметите, что речь идет не о безопасности, а о лучших практиках
Мулескиннер
7
Из вашего отредактированного ответа я вижу, что jQuery действительно проверяет, назначен ли класс allready перед его добавлением, т.е. было бы плохой практикой делать проверку самостоятельно / спасибо
Muleskinner
5
@Muleskinner, вот что я имел в виду.
Raynos
41
@Raynos: Простая проверка в консоли показала бы, что вызов addClass несколько раз с одним и тем же классом безопасен. Тем не менее, этот вопрос был одним из самых популярных, когда я искал ответ в Google ... Даже тривиальные вещи, которые хорошо задокументированы в другом месте, имеют место в Stack Overflow.
eirirlar
10
В этом ответе слишком много отношения. Мог бы ответить тактично.
dreadwail
4

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

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

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

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

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

Игве Калу
источник
1
$("label")
  .not(".foo")
  .addClass("foo");
ו ישראל שרות לקוחות
источник