Spec-Zone.ru › Web APIs

Введение в DOM

Модель объекта документа (DOM) — это представление данных об объектах, составляющих структуру и содержимое веб-документа. Это руководство познакомит вас с DOM, покажет, как DOM представляет HTML-документ в памяти и как использовать API для создания веб-контента и приложений.

Что такое DOM?

Модель объекта документа (DOM) — это программно-ориентированный интерфейс для веб-документов. Она представляет страницу таким образом, чтобы программы могли изменять ее структуру, стиль и содержимое. DOM представляет документ в виде узлов и объектов; таким образом, языки программирования могут взаимодействовать со страницей.

Веб-страница — это документ, который может быть отображен в окне браузера или показан как исходный HTML. В обоих случаях это один и тот же документ, но представление Модели объекта документа (DOM) позволяет его изменять. Как объектно-ориентированное представление веб-страницы, его можно изменять с помощью языка сценариев, такого как JavaScript.

Например, DOM определяет, что метод querySelectorAll в этом фрагменте кода должен возвращать список всех элементов <p> в документе:

const paragraphs = document.querySelectorAll("p");
// paragraphs[0] is the first <p> element
// paragraphs[1] is the second <p> element, etc.
alert(paragraphs[0].nodeName);

Все свойства, методы и события, доступные для управления и создания веб-страниц, организованы в объекты. Например, объект document, представляющий сам документ, любые объекты table, реализующие интерфейс DOM HTMLTableElement для доступа к HTML-таблицам, и так далее, являются объектами.

DOM построен с использованием нескольких API, которые работают вместе. Ядро DOM определяет сущности, описывающие любой документ и объекты внутри него. Это дополняется по мере необходимости другими API, которые добавляют новые функции и возможности в DOM. Например, API HTML DOM добавляет поддержку представления HTML-документов в ядро DOM, а API SVG добавляет поддержку представления SVG-документов.

DOM и JavaScript

Предыдущий короткий пример, как и почти все примеры, написан на JavaScript. То есть, он написан на JavaScript, но использует DOM для доступа к документу и его элементам. DOM — это не язык программирования, но без него язык JavaScript не имел бы никакой модели или понятия веб-страниц, HTML-документов, SVG-документов и их составных частей. Весь документ, заголовок, таблицы внутри документа, заголовки таблиц, текст внутри ячеек таблицы и все другие элементы документа являются частями модели объекта документа для этого документа. К ним можно получить доступ и управлять ими с помощью DOM и языка сценариев, такого как JavaScript.

DOM не является частью языка JavaScript, а является вместо этого веб-API, используемым для создания веб-сайтов. JavaScript также может использоваться в других контекстах. Например, Node.js выполняет программы JavaScript на компьютере, но предоставляет другой набор API, и API DOM не является основной частью среды выполнения Node.js.

DOM был разработан как независимый от конкретного языка программирования, что делает структурное представление документа доступным из единого, согласованного API. Даже если большинство веб-разработчиков будут использовать DOM только через JavaScript, реализации DOM могут быть созданы для любого языка, как показывает этот пример на Python:

# Python DOM example
import xml.dom.minidom as m
doc = m.parse(r"C:\Projects\Py\chap1.xml")
doc.nodeName # DOM property of document object
p_list = doc.getElementsByTagName("para")

Для получения дополнительной информации о технологиях, участвующих в написании JavaScript в веб-приложениях, см. обзор технологий JavaScript.

Доступ к DOM

Вам не нужно делать ничего особенного, чтобы начать использовать DOM. Вы используете API напрямую в JavaScript из того, что называется скриптом, программой, выполняемой браузером.

Когда вы создаете скрипт, будь то встроенный в элемент <script> или включенный в веб-страницу, вы можете сразу же начать использовать API для объектов document или window для управления самим документом или любыми элементами на веб-странице (потомками документа). Ваша работа с DOM может быть такой простой, как следующий пример, который выводит сообщение в консоль, используя функцию console.log():

<body onload="console.log('Welcome to my home page!');">
  …
</body>

Поскольку в целом не рекомендуется смешивать структуру страницы (написанной на HTML) и манипулирование DOM (написанное на JavaScript), части JavaScript будут сгруппированы здесь и отделены от HTML.

Например, следующая функция создает новый элемент h1, добавляет текст в этот элемент и добавляет его в дерево документа:

<html lang="en">
  <head>
    <script>
      // run this function when the document is loaded
      window.onload = () => {
        // create a couple of elements in an otherwise empty HTML page
        const heading = document.createElement("h1");
        const headingText = document.createTextNode("Big Head!");
        heading.appendChild(headingText);
        document.body.appendChild(heading);
      };
    </script>
  </head>
  <body></body>
</html>

Основные типы данных

Эта страница пытается описать различные объекты и типы простым языком. Но существует ряд различных типов данных, которые передаются через API, о которых вам следует знать.

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

В следующей таблице кратко описаны эти типы данных.

Тип данных (интерфейс) Описание
Document Когда член возвращает объект типа document (например, свойство ownerDocument элемента возвращает document, к которому он принадлежит), этот объект является корневым объектом document сам по себе. Раздел «Ссылка на document объекта DOM» описывает объект document.
Node Каждый объект, расположенный внутри документа, является узлом определенного типа. В HTML-документе объект может быть узлом элемента, но также и узлом текста или атрибута.
Element Тип element основан на node. Он относится к элементу или узлу типа element, возвращаемому членом API DOM. Вместо того, чтобы, например, говорить, что метод document.createElement() возвращает ссылку на объект node, мы просто говорим, что этот метод возвращает element , который был только что создан в DOM. Объекты element реализуют интерфейс DOM Element и также более базовый интерфейс Node , оба из которых включены в этот справочник. В HTML-документе элементы дополнительно расширяются интерфейсом HTMLElement API HTML DOM, а также другими интерфейсами, описывающими возможности определенных типов элементов (например, HTMLTableElement для элементов <table>).
NodeList nodeList — это массив элементов, например, тот, который возвращает метод document.querySelectorAll(). Элементы nodeList доступны по индексу двумя способами:
  • list.item(1)
  • list[1]
Эти два варианта эквивалентны. В первом случае item() — единственный метод объекта nodeList. Второй вариант использует стандартную синтаксическую конструкцию для массивов, чтобы получить второй элемент списка.
Attr Когда attribute возвращается членом (например, методом createAttribute()), это ссылка на объект, который раскрывает специальный (хотя и небольшой) интерфейс для атрибутов. Атрибуты — это узлы в DOM, так же как и элементы, хотя вы редко используете их как таковые.
NamedNodeMap namedNodeMap — это как массив, но элементы доступны по имени или индексу, хотя последний случай — просто удобство для перечисления, так как они не упорядочены в списке. У namedNodeMap есть метод item() для этой цели, и вы также можете добавлять и удалять элементы из namedNodeMap .

Также следует учитывать некоторые особенности терминологии. Принято называть любой узел Attr attribute , например, и называть массив узлов DOM nodeList . Вы встретите эти и другие термины на протяжении всего руководства.

Интерфейсы DOM

Это руководство посвящено объектам и тем вещам, которые вы можете использовать для управления иерархией DOM. Понимание того, как они работают, может быть сложным в некоторых местах. Например, объект, представляющий элемент HTML form , получает свойство name из интерфейса HTMLFormElement, но свойство className из интерфейса HTMLElement. В обоих случаях свойство, которое вам нужно, находится в виде объекта.

Но взаимоотношения между объектами и интерфейсами, которые они реализуют в DOM, могут быть сложными, поэтому этот раздел пытается сказать кое-что о фактических интерфейсах в спецификации DOM и о том, как они предоставляются.

Интерфейсы и объекты

Многие объекты реализуют несколько разных интерфейсов. Например, объект таблицы реализует специализированный HTMLTableElement интерфейс, который включает такие методы, как createCaption и insertRow. Но поскольку он также является HTML-элементом, table реализует интерфейс Element, описанный в главе справки DOM Element. И, наконец, поскольку HTML-элемент также, с точки зрения DOM, является узлом в дереве узлов, составляющих модель объекта для HTML- или XML-страницы, объект таблицы также реализует более базовый интерфейс Node, от которого Element происходит.

Когда вы получаете ссылку на объект table, как в следующем примере, вы обычно используете все три этих интерфейса взаимозаменяемо для объекта, возможно, даже не зная об этом.

const table = document.getElementById("table");
const tableAttrs = table.attributes; // Node/Element interface
for (let i = 0; i < tableAttrs.length; i++) {
  // HTMLTableElement interface: border attribute
  if (tableAttrs[i].nodeName.toLowerCase() === "border") {
    table.border = "1";
  }
}
// HTMLTableElement interface: summary attribute
table.summary = "note: increased border";

Основные интерфейсы в DOM

В этом разделе перечислены некоторые из наиболее часто используемых интерфейсов в DOM. Цель заключается не в том, чтобы здесь описывать, что делают эти API, а в том, чтобы дать вам представление о типах методов и свойств, которые вы будете часто видеть при использовании DOM. Эти распространённые API используются в более длинных примерах в главе «Примеры DOM» в конце этой книги.

Объекты document и window — это объекты, интерфейсы которых вы обычно используете чаще всего при программировании с помощью DOM. Проще говоря, объект window представляет собой что-то вроде браузера, а объект document — это корень самого документа. Element наследуется от универсального интерфейса Node, и вместе эти два интерфейса предоставляют многие методы и свойства, которые вы используете для отдельных элементов. Эти элементы также могут иметь специфические интерфейсы для работы с данными, которые эти элементы хранят, как в примере объекта table в предыдущем разделе.

Ниже приведён краткий список распространённых API в сценариях работы с веб- и XML-страницами с использованием DOM.

  • document.querySelector()
  • document.querySelectorAll()
  • document.createElement()
  • Element.innerHTML
  • Element.setAttribute()
  • Element.getAttribute()
  • EventTarget.addEventListener()
  • HTMLElement.style
  • Node.appendChild()
  • window.onload
  • window.scrollTo()

Примеры

Установка текстового содержимого

В этом примере используется элемент <div>, содержащий элемент <textarea> и два элемента <button>. При нажатии первой кнопки мы устанавливаем некоторый текст в <textarea>. При нажатии второй кнопки мы очищаем текст. Мы используем:

  • Document.querySelector() для доступа к <textarea> и кнопке
  • EventTarget.addEventListener() для прослушивания нажатий кнопок
  • Node.textContent для установки и очистки текста.

HTML

<div class="container">
  <textarea class="story"></textarea>
  <button id="set-text" type="button">Set text content</button>
  <button id="clear-text" type="button">Clear text content</button>
</div>

CSS

.container {
  display: flex;
  gap: 0.5rem;
  flex-direction: column;
}

button {
  width: 200px;
}

JavaScript

const story = document.body.querySelector(".story");

const setText = document.body.querySelector("#set-text");
setText.addEventListener("click", () => {
  story.textContent = "It was a dark and stormy night...";
});

const clearText = document.body.querySelector("#clear-text");
clearText.addEventListener("click", () => {
  story.textContent = "";
});

Результат

Добавление дочернего элемента

В этом примере используется элемент <div>, содержащий элемент <div> и две кнопки <button>. При нажатии первой кнопки мы создаём новый элемент и добавляем его как дочерний к <div>. При нажатии второй кнопки мы удаляем дочерний элемент. Мы используем:

  • Document.querySelector() для доступа к <div> и кнопкам
  • EventTarget.addEventListener() для прослушивания нажатий кнопок
  • Document.createElement для создания элемента
  • Node.appendChild() для добавления дочернего элемента
  • Node.removeChild() для удаления дочернего элемента.

HTML

<div class="container">
  <div class="parent">parent</div>
  <button id="add-child" type="button">Add a child</button>
  <button id="remove-child" type="button">Remove child</button>
</div>

CSS

.container {
  display: flex;
  gap: 0.5rem;
  flex-direction: column;
}

button {
  width: 100px;
}

div.parent {
  border: 1px solid black;
  padding: 5px;
  width: 100px;
  height: 100px;
}

div.child {
  border: 1px solid red;
  margin: 10px;
  padding: 5px;
  width: 80px;
  height: 60px;
  box-sizing: border-box;
}

JavaScript

const parent = document.body.querySelector(".parent");

const addChild = document.body.querySelector("#add-child");
addChild.addEventListener("click", () => {
  // Only add a child if we don't already have one
  // in addition to the text node "parent"
  if (parent.childNodes.length > 1) {
    return;
  }
  const child = document.createElement("div");
  child.classList.add("child");
  child.textContent = "child";
  parent.appendChild(child);
});

const removeChild = document.body.querySelector("#remove-child");
removeChild.addEventListener("click", () => {
  const child = document.body.querySelector(".child");
  parent.removeChild(child);
});

Результат

Спецификации

Спецификация
DOM

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API