JavaScript | Как получить все имена HTML-классов из DOM-документа?

JavaScript | Как получить все имена HTML-классов из DOM-документа?

Как получить все названия классов на HTML-странице?

Мы хотим знать какие именно названия HTML-атрибутов class можно встретить в качестве его значений во всём документе. Как это сделать?

 

Решение

[...new Set([...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity).sort())]

или

[...new Set([...document.all].map(i=>[...i.classList]).flat(Infinity).sort())]

Данное выражение вернёт нам сортированный массив из уникальных строк, которые являются значениями классов всех элементов в документе.

 

Как это работает?

Шаг № 1

Сначала мы обращаемся к объекту документа (document), который сформировался на нашей вкладке браузера, после получения строки с данными с сервера. Браузер синтаксически проанализировал строку с HTML-разметкой и при помощи «Объектной Модели Документа» создал для нас специальный JavaScript-объект, который хранит в себе все объекты HTML-элементов.

document

У этого объекта есть целый стандарт, который определяет множество методов и свойств для работы с этим объектом.

Скриншот главной страницы стандарта DOM от 19 декабря 2021 года:

Скриншот главной страницы стандарта DOM от 19 декабря 2021 года
Скриншот главной страницы стандарта DOM от 19 декабря 2021 года

 

Шаг № 2

Далее есть 2 пути получения всех объектов HTML-элементов:

  1. Из стандарта DOM мы можем использовать метод querySelectorAll()
  2. Из стандарта HTML мы можем использовать УСТАРЕВШИЙ атрибут all

Какой из них выбрать — решать вам. На 2022 год оба работают в браузерах.

Разница заключается в том, что в метод querySelectorAll() нужно передавать специальный CSS-селектор, который обозначается строкой со звёздочкой — «*«

document.querySelectorAll('*')

или

document.all

Второе важное отличие в том, какой объект мы получаем на выходе.

  • querySelectorAll(‘*‘), то возвращается объект класса NodeList
  • all, то возвращается объект класса HTMLAllCollection

Пример вызова на случайном документе:

метод querySelectorAll('*') и атрибут all на случайном документе - JavaScript
метод querySelectorAll(‘*’) и атрибут all на случайном документе — JavaScript

 

Шаг № 3

Стандартные JavaScript-методы экземпляров класса Array не работают с NodeList и HTMLAllCollection. Это значит, что мы не сможем «пробегать» по объектам HTML-элементов и получать(извлекать) нужные нам данные. Нам нужна конвертация в массив для получения полного функционала для манипулирования с объектами HTML-элементов этого документа.

Делается это при помощи spread () оператора и литерального объявления массива []:

[...document.querySelectorAll('*')]

или

[...document.all]

Эти два выражения вернут нам стандартный массив языка JavaScript.

Преобразовали NodeList и HTMLAllCollection в Array
Преобразовали NodeList и HTMLAllCollection в Array

 

Шаг № 4

Теперь у нас открыта возможность «пробегания» по всем элементам массива для «выдёргивания» значений из нужных свойств объектов HTML-элементов.

Это умеет делать метод map(). Так как нас интересуют значения, которые лежат в классах HTML-элементов, то нам нужно обращаться к такому свойству, которое называется classList.

[...document.querySelectorAll('*')].map(i=>i.classList)

или

[...document.all].map(i=>i.classList)

Это свойство будет возвращать нам объекты класса DOMTokenList. По сути это те же самые массивы (смотри шаг № 3).

Получили объекты класса DOMTokenList всех HTML-элементов в документе - JavaScript
Получили объекты класса DOMTokenList всех HTML-элементов в документе — JavaScript

Обратите внимание, что некоторые объекты DOMTokenList будут пустыми. Это нормально т. к. не все HTML-элементы могут иметь свои классы.

 

Шаг № 5

Нам снова нужна конвертация в массив из объектов DOMTokenList. То есть нам нужно уже сразу возвращать массивы, на каждой итерации функции обратного вызова метода map().

[...document.querySelectorAll('*')].map(i=>[...i.classList])

или

[...document.all].map(i=>[...i.classList])
Получили объекты класса Array всех HTML-элементов в документе - JavaScript
Получили объекты класса Array всех HTML-элементов в документе — JavaScript

Теперь у нас есть самая удобная структура — массив состоящий только из массивов.

 

Шаг № 6

Выпаковывание содержимого всех внутренних массивов на один уровень главного массива. Выполнить эту задачу способен метод flat(), который может принять в себя число положительной бесконечности — Infinity. Бесконечность даёт гарантию максимального погружения в глубину массива. До самого дна, если это потребуется.

[...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity)

или

[...document.all].map(i=>[...i.classList]).flat(Infinity)

Мы получим все названия классов в строковом виде, которые встречаются в текущем документе. Причём некоторые будут повторяться т.к. разные HTML-элементы могут содержать одинаковые значения классов.

Получили все строковые значения имён классов, встречающихся в документе в древовидном порядке - JavaScript
Получили все строковые значения имён классов, встречающихся в документе в древовидном порядке — JavaScript

 

 

Шаг № 7

Сортировка результатов для удобного восприятия итогового массива (и его возможного вывода в графическое представление).

[...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity).sort()

или

[...document.all].map(i=>[...i.classList]).flat(Infinity).sort()
Отсортировали все названия классов по логике метода sort() - JavaScript
Отсортировали все названия классов по логике метода sort() — JavaScript

 

Шаг № 8

На этом шаге нам нужно избавиться от дублей, чтобы получить только уникальные строковые значения из массива JavaScript. В этом нам поможет конструктор класса Set, который стандартно заложен в ГЛОБАЛЬНОМ объекте языка.

new Set([...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity).sort())

или

new Set([...document.all].map(i=>[...i.classList]).flat(Infinity).sort())

Нам вернётся объект — экземпляр класса Set.

Получили экземпляр класса Set (уникальный набор) значений имён классов документа - JavaScript
Получили экземпляр класса Set (уникальный набор) значений имён классов документа — JavaScript

 

Шаг № 9

Финальным шагом будет конвертация объекта Set в Array.

[...new Set([...document.querySelectorAll('*')].map(i=>[...i.classList]).flat(Infinity).sort())]

или

[...new Set([...document.all].map(i=>[...i.classList]).flat(Infinity).sort())]

Получили массив из имён классов HTML-элементов - JavaScript
Получили массив из имён классов HTML-элементов — JavaScript

 

Итог

Теперь можно анализировать этот массив для дальнейших манипуляций с кодом своей собственной программы.

 

Информационные ссылки

JavaScript | Есть ли HTML-класс в DOM-документе?

HTML | Интерфейс HTMLAllCollection

Стандарт HTML — Раздел «2.6.2.1 The HTMLAllCollection interface» — https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#the-htmlallcollection-interface