querySelector и querySelectorAll против getElementsByClassName и getElementById в JavaScript

querySelector и querySelectorAll против getElementsByClassName и getElementById в JavaScript

Для этого ответа я обращаюсь к querySelector и querySelectorAll как querySelector * и к getElementById , getElementsByClassName , getElementsByTagName и getElementsByName как getElement *.

Эти понятия обобщены в следующей таблице.

  • HTMLCollections не так массивны, как NodeLists, и не поддерживают .forEach (). Я считаю, что оператор распространения полезен, чтобы обойти это:

    [...document.getElementsByClassName("someClass")].forEach()]

  • Каждый элемент и глобальный document имеют доступ ко всем этим функциям, кроме getElementsByName , который реализован только в document .

  • Цепочка вызовов getElement * вместо использования querySelector * улучшит производительность, особенно на очень больших DOM. Даже на небольших DOM и / или с очень длинными цепями это обычно быстрее. Однако, если вы не знаете, что вам нужна производительность, читаемость querySelector * должна быть предпочтительной. querySelectorAll часто сложнее переписать, потому что вы должны выбирать элементы из NodeList или HTMLCollection на каждом шаге. Например, следующий код не работает:

    document.getElementsByClassName("someClass").getElementsByTagName("div")

    потому что вы можете использовать getElements * только для отдельных элементов, но не для коллекций. Например:

    document.querySelector("#someId .someClass div")

    может быть написано как:

    document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0]

    Обратите внимание на использование [0] для получения только первого элемента коллекции на каждом шаге, который возвращает коллекцию, в результате чего в конце появляется один элемент, как и в querySelector .

  • Поскольку все элементы имеют доступ как к вызовам querySelector *, так и к getElement *, вы можете создавать цепочки, используя оба вызова, что может быть полезно, если вы хотите повысить производительность, но не можете избежать запроса querySelector, который нельзя записать в терминах вызовов getElement *. ,

  • Хотя, как правило, легко определить, можно ли писать селектор, используя только вызовы getElement *, есть один случай, который может быть неочевидным:

    document.querySelectorAll(".class1.class2")

    можно переписать как

    document.getElementsByClassName("class1 class2")

  • Использование getElement * для статического элемента, извлеченного с помощью querySelector *, приведет к тому, что элемент будет действителен по отношению к статическому подмножеству DOM, скопированному с помощью querySelector, но не будет действителен по отношению к полному DOM документа … вот где простое живая / статическая интерпретация элементов начинает разваливаться. Вам, вероятно, следует избегать ситуаций, когда вам придется беспокоиться об этом, но если вы это сделаете, помните, что querySelector * вызывает элементы копирования, которые они находят, прежде чем возвращать ссылки на них, но getElement * вызывает выборку прямых ссылок без копирования.

  • Ни один API не указывает, какой элемент должен быть выбран первым, если есть несколько совпадений.

  • Поскольку querySelector выполняет итерацию по DOM до тех пор, пока не найдет совпадение (см. Основное отличие № 2), вышеприведенное также подразумевает, что вы не можете полагаться на положение элемента, который вы ищете в DOM, чтобы гарантировать его быстрое обнаружение — браузер может проходить через DOM назад, вперед, сначала в глубину, в ширину или в противном случае.

  • Понравилась статья? Поделиться с друзьями:
    JavaScript & TypeScript
    Adblock
    detector