С помощью JavaScript можно изменять структуру HTML-документа, напрямую модифицируя объектную модель документа (DOM, Document Object Model). Объектная модель обеспечивает доступ ко всем тегам и их атрибутам, позволяет создавать, удалять и изменять элементы
HTML-элементы представляют из себя дерево, в котором узлы - это элементы. Вложенность HTML-элементов обозначается дочерними связями в дереве
Всего существует 12 типов узлов в объектной модели:
ELEMENT_NODE = 1ATTRIBUTE_NODE = 2TEXT_NODE = 3ELEMENT_NODE представляет элемент, который задается HTML-тегом, а TEXT_NODE - это узел с сырым текстом
Так <p>Это параграф</p> преобразуется в дерево с узлом p типа ELEMENT_NODE и дочерний текстовый узел Это параграф типа TEXT_NODE
Корень дерева в JavaScript представлен объектом document. От него можно получить непосредственно элемент html с помощью document.documentElement и элемент body с помощью document.body
В JavaScript есть 6 основных методов получения элементов из дерева объектной модели:
document.getElementById(id) возвращает элемент с идентификатором id (наиболее рекомендованный метод для работы с элементами)document.getElementsByTagName(tag) возвращает массив элементов с тегом tagdocument.getElementsByName(elementName) возвращает массив элементов, у которых атрибут name равен elementNamedocument.getElementsByClassName(elementClass) возвращает массив элементов с классом elementClassdocument.querySelector(selector) возвращает первый элемент, который соответствует селектору selectordocument.querySelector(selector) возвращает массив элементов, которые соответствуют селектору selectorДалее от них можно идти по дереву с помощью свойств:
node.parentNode - родительский узелnode.childNodes[i] - дочерние узлыnode.firstChild - первый дочерний узелnode.lastChild - последний дочерний узелnode.previousSibling - предыдущий соседний узел у того же родителяnode.nextSibling - следующий соседний узелС ними нужно быть осторожными, так как некоторые браузеры обрабатывают новую строку в HTML-документе как текстовый узел
Еще узлы имеют такие свойства:
node.nodeType - тип узла (число из перечислений, 1 для обычного узла, 3 для текстового)node.tagName - тег узлаnode.nodeName - имя узла. Если узел - это тег, то это имя тега, если текст, то #text, если комментарий, то #comment и так далееСодержимое элемента можно узнать или заменить с помощью:
node.innerText - текст, отображаемый в окне браузера, внутри тегаnode.outerText - текст, отображаемый в окне браузера, включая исходный тегnode.innerHTML - HTML-код внутри тегаnode.outerHTML - HTML-код, включая тегЗначения innerText и outerText равны, однако при записи строка принимается как экранированный текст, а не HTML-код, поэтому запись в outerText ведет к удалению исходного элемента
Запись свойств innerHTML и outerHTML ведет к парсингу нового значения и изменения объектной модели. Для изменения HTML-страницы предпочтительнее использовать не эти свойства, принимающие строки, а методы node.appendChild, node.insertBefore и другие
Также есть свойство node.textContent, которое показывает весь текст, включая скрытый с помощью display: none
Для редактирования дерева есть методы:
const elem = document.createElement(tagName) создает элемент с тегом tagName, но только на уровне интерпретатора JavaScriptconst elem = document.createTextNode(text) аналогично создает текстовый узелnode.appendChild(elem) добавляет этот элемент в дерево в качестве дочернего узлаnode.insertBefore(elem) добавляет этот элемент в дерево перед узлом nodenode.removeChild(childNode) удаляет дочерний элемент childNode из дереваnode.remove() удаляет этот элемент из дереваПри вызове таких методов происходит событие пересчета дерева (reflow event), который можно поймать в своем скрипте (об этом позже)
Для редактирования узлов есть такие методы:
node.createAttribute(name) создает атрибут namenode.createAttribute(name, value) создает атрибут name со значением valuenode.removeAttribute(name) удаляет атрибут namenode.getAttribute(name) возвращает значение атрибута nameНа жизненном цикле веб-страницы может происходить множество событий, например, нажатие кнопки или прокрутка колеса мыши
Событие - это сигнал браузера о том, что что-то произошло. Для них браузер предоставляет API
Так событие возникает для какого-то элемента, и браузер вызывает для этого события привязанные к элементу функции JavaScript
События можно добавлять:
onXYZ="myFunction()", где XYZ - тип события, например: <button onclick="alert('Клик!')">Клик!</buttonс помощью свойства:
elem.onclick = function() {
alert('Клик');
};
с помощью метода elem.addEventListener(eventType, callback):
elem.addEventListener("click", function() {
alert('Клик');
});
Такой метод является наиболее предпочтительным, потому что предыдущие ограничены только одной функцией, которые отвечают на событие. addEventListener позволяет добавить множество обработчиков
С помощью событий можно обрабатывать нажатия на элемент (click), наведение на элемент (mouseover), на правый клик мыши (contextmenu), на нажатие клавиатуры (keydown), на отправку формы (submit) и многое другое
Самое важное событие - DOMContentLoaded у document. Оно вызывается тогда, когда дерево объектной модели документа полностью загружено браузером, и над ним безопасно работать внутри JavaScript-кода. Поэтому весь код, требующий работы с элементами ограничивают в обрабатывающей функции:
document.addEventListener("DOMContentLoaded", function () {
const elem = document.getElementById("myid");
// ...
});