Какая разница между живой и не живой коллекцией в Javascript-селекторах?

Как я могу узнать, в чем разница между живой, а не живой коллекцией.

Согласно моим исследованиям:

A live: когда изменения в DOM отражаются в коллекции. Содержимое изменяется после изменения node.

A Не в сети: когда любые изменения в DOM не влияют на содержимое коллекции.

document.getElementsByClassName() - это HTMLCollection и является живым.

document.getElementsByTagName() - это HTMLCollection и является живым.

document.getElementsByName() - это NodeList и находится в режиме реального времени.

document.querySelectorAll() является NodeList и не является живым.

Почему document.querySelectorAll не работает?

Я знаю, что:

HTMLCollection содержит только узлы Elements NodeList содержит узлы элементов и текстовые узлы.

2 ответа

Эти

document.getElementsByClassName()
document.getElementsByTagName()
document.getElementsByName()

являются живыми, потому что они являются наблюдателями внутренних коллекций, поддерживаемых двигателями. Это техническое обслуживание строго не требуется, но его легко достичь.

document.querySelectorAll()

не является живым, потому что результат вычисляется каждый раз, когда вы его запрашиваете. Обслуживание живой коллекции слишком дорого, так как каждая модификация (содержимое, атрибуты, классы) DOM в этом случае потребует переоценки каждого элемента в коллекции - O(N*M) задача, где N - количество всех элементов в DOM (наихудший случай) и M количество активных коллекций querySelectorAll().


Из DOM spec

Коллекция представляет собой объект, который представляет списки узлов DOM. collection может быть как живым, так и статическим. Если не указано иное указано collection должно быть live.

Если collection live, то атрибуты и методы на этот объект должен работать с фактическими базовыми данными, а не с моментальным снимком данных.

Когда создается collection, фильтр и корень связаны с ним.

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

Причины, по которым querySelectorAll возвращает статический NodeList, могут иметь возможность разрешать более сложные селекторы.

Например, селектор L4 может вводить такие вещи, как псевдо-класс :has(). Вероятно, поскольку он не может быть реализован с разумной производительностью, он будет доступен только в querySelectorAll, но не в таблицах стилей.

Если коллекция, возвращаемая querySelectorAll, была вживую, тогда эти сложные селекторы нужно было бы пересчитать много раз, и это было бы так дорого.

licensed under cc by-sa 3.0 with attribution.