Управление элементами на странице с помощью DOM

Основой HTML-документа являются теги. В соответствии с объектной моделью документа («Document Object Model», коротко DOM), каждый HTML-тег является объектом. Вложенные теги являются «детьми» родительского элемента. Текст, который находится внутри тега, также является объектом.

Все эти объекты доступны при помощи JavaScript, мы можем использовать их для изменения страницы.

Пример DOM для простой HTML-страницы:

<!DOCTYPE HTML>
<html>
<head>
  <title>Заголовок страницы</title>
</head>
<body>
  <p class="paragraph" id="maintext">Информация на странице.</p>
</body>
</html>

Пустые узлы "#text:" в DOM-дереве - это пробелы и переводы строк между тегами в исходном HTML-документе. Для них тоже строятся узлы. Это необходимо учитывать. Также стоит обратить внимание, что текстовые узлы не могут иметь потомков, т.е. - это листья в DOM-дереве.

Чтобы посмотреть структуру DOM, можно воспользоваться инструментом Live DOM Viewer (см. страницу "Ресурсы").

Каждый DOM-элемент является объектом и предоставляет свойства для манипуляции своим содержимым, для доступа к родителям и потомкам.

Для манипуляций с DOM используется объект document. Используя document, можно получать нужный элемент дерева и управлять им.

Первая точка входа – document.documentElement. Это свойство ссылается на DOM-объект для тега <html>.

<HTML> = document.documentElement

Вторая точка входа – document.body, который соответствует тегу <body>.

<BODY> = document.body

Обход дерева DOM возможен по узлам с помощью следующих методов:

  • childNodes: свойство для доступа ко всем прямым дочерним узлам одного элемента. Это будет объект, похожий на массив, который можно будет «перебрать» по индексу.
  • firstChild: доступ к первому элементу в массиве childNodes (тоже самое, что и childNodes[0]).
  • lastChild: доступ к последнему элементу в массиве childNodes.
  • parentNode: доступ к родительскому узлу текущего узла.
  • nextSibling: доступ к следующему узлу на том же уровне в дереве DOM (к следующему соседнему узлу).
  • previousSibling: доступ к предыдущему узлу того же уровня в дереве DOM.

Например, в нашем дереве цвет текста в абзаце можно сменить так:

document.body.childNodes[1].style.color = 'red';

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

  • Метод getElementsByTagName() возвращает коллекцию/список активных узлов, связанных с указанным тегом. Эта коллекция похожа на массив в том, что у нее есть свойство размера (length). Поскольку это массивоподобный объект, мы можем получить доступ к каждому узлу через индекс, от 0 до общей длины коллекции:
document.getElementsByTagName('p')[0].style.color = 'red';
  • Аналогично работает метод getElementsByClassName(), позволяя получить коллекцию/список активных узлов с одним и тем же классом:
document.getElementsByClassName('paragraph')[0].style.color = 'red';
  • Метод getElementById() - позволяет в точности выбрать конкретный элемент по его атрибуту ID:
 document.getElementById('maintext').style.color = 'red';
  • И самый эффективный метод querySelector() - позволяет в точности выбрать первый элемент на странице по совокупности селекторов, используя каскадное перечисление селекторов как в CSS:
 document.querySelector('#maintext').style.color = 'red';

Для работы с элементами на веб-странице можно использовать как функциональность типа Node, который представляет любой узел веб-страницы (описаны выше), так и функциональность типа HTMLElement, который собственно представляет элемент. Если использовать предыдущие методы доступа к узлам дерева, то доступ к тексту, заключенному внутри парного тега, будет осуществляться путем перебора дочерних узлов, содержащих сам текст. Это неудобно. Более простой способ использовать специальные методы:

  • tagName: возвращает тег элемента
  • textContent: представляет текстовое содержимое элемента
  • innerText: представляет текстовое содержимое элемента (аналогично textContent)
  • innerHTML: представляет html-код элемента

Пример смены содержимого заголовка h1 на новый при открытии страницы:

<body>
    <h1 id="header">Заголовок</h1>
    <script>
     document.getElementById("header").innerText = "Новый заголовок";
    </script>
</body>

Несмотря на большое сходство методов textContent и innerText, между ними есть небольшие различия:

  • textContent получает содержимое всех элементов, включая <script> и <style>, тогда как innerText этого не делает
  • innerText умеет считывать стили и не возвращает содержимое скрытых элементов, тогда как textContent этого не делает.
  • innerText позволяет получить CSS, а textContent — нет.

Ни textContent, ни innerText не позволяют работать с кодом самого html элемента. Для управления html применяется свойство innerHTML:

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

<body>
    <h1 id="header">Заголовок</h1>
    <script>
    document.getElementById("header").innerHTML = "<span style='color:green;'>Заголовок заменен на зеленый текст</span>";
    </script>
</body>

Для работы со стилевыми свойствами элементов в JavaScript применяются, главным образом, два подхода:

  • Изменение свойства style
  • Изменение значения атрибута class

Свойство style представляет сложный объект CSSStyleDeclaration и напрямую сопоставляется с атрибутом style html-элемента. Этот объект содержит набор свойств CSS, к которым можно обратиться следующим образом:

document.getElementById('maintext').style.color = 'green';
document.getElementById('maintext').style.fontSize= '24px';

При работе со свойствами стиля объекта CSSStyleDeclaration все значения должны задаваться в виде строк. Если имя CSS-свойства содержит дефисы, имя свойства объекта CSSStyleDeclaration образуется путем удаления дефисов и перевода в верхний регистр буквы, непосредственно следующей за каждым из них. Другими словами, CSS-свойство border-left-width доступно через свойство borderLeftWidth, а к CSS-свойству font-family можно обратиться через свойство fontFamily.

Кроме того, когда CSS-свойство, такое как float, имеет имя, совпадающее с зарезервированным словом языка JavaScript, к этому имени добавляется префикс «css», чтобы создать допустимое имя свойства объекта CSSStyleDeclaration. То есть, чтобы прочитать или изменить значение CSS-свойства float элемента, следует использовать свойство cssFloat объекта CSSStyleDeclaration.

Направление: