Что является свойством объекта входящего в dom
Перейти к содержимому

Что является свойством объекта входящего в dom

  • автор:

DOM-дерево

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

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

Например, document.body – объект для тега .

Если запустить этот код, то станет красным на 3 секунды:

document.body.style.background = 'red'; // сделать фон красным setTimeout(() => document.body.style.background = '', 3000); // вернуть назад

Это был лишь небольшой пример того, что может DOM. Скоро мы изучим много способов работать с DOM, но сначала нужно познакомиться с его структурой.

Пример DOM

Начнём с такого, простого, документа:

   О лосях  Правда о лосях. 

DOM – это представление HTML-документа в виде дерева тегов. Вот как оно выглядит:

На рисунке выше узлы-элементы можно кликать, и их дети будут скрываться и раскрываться.

Каждый узел этого дерева – это объект.

Теги являются узлами-элементами (или просто элементами). Они образуют структуру дерева: – это корневой узел, и его дочерние узлы и т.д.

Текст внутри элементов образует текстовые узлы, обозначенные как #text . Текстовый узел содержит в себе только строку текста. У него не может быть потомков, т.е. он находится всегда на самом нижнем уровне.

Например, в теге есть текстовый узел «О лосях» .

Обратите внимание на специальные символы в текстовых узлах:

  • перевод строки: ↵ (в JavaScript он обозначается как \n )
  • пробел: ␣

Пробелы и переводы строки – это полноправные символы, как буквы и цифры. Они образуют текстовые узлы и становятся частью дерева DOM. Так, в примере выше в теге есть несколько пробелов перед , которые образуют текстовый узел #text (он содержит в себе только перенос строки и несколько пробелов).

Существует всего два исключения из этого правила:

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

В остальных случаях всё просто – если в документе есть пробелы (или любые другие символы), они становятся текстовыми узлами дерева DOM, и если мы их удалим, то в DOM их тоже не будет.

Здесь пробельных текстовых узлов нет:

 О лосяхПравда о лосях.

Пробелы по краям строк и пробельные текстовые узлы скрыты в инструментах разработки

Когда мы работаем с деревом DOM, используя инструменты разработчика в браузере (которые мы рассмотрим позже), пробелы в начале/конце текста и пустые текстовые узлы (переносы строк) между тегами обычно не отображаются.

Таким образом инструменты разработки экономят место на экране.

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

Автоисправление

Если браузер сталкивается с некорректно написанным HTML-кодом, он автоматически корректирует его при построении DOM.

Например, в начале документа всегда должен быть тег . Даже если его нет в документе – он будет в дереве DOM, браузер его создаст. То же самое касается и тега .

Например, если HTML-файл состоит из единственного слова «Привет» , браузер обернёт его в теги и , добавит необходимый тег , и DOM будет выглядеть так:

При генерации DOM браузер самостоятельно обрабатывает ошибки в документе, закрывает теги и так далее.

Есть такой документ с незакрытыми тегами:

…Но DOM будет нормальным, потому что браузер сам закроет теги и восстановит отсутствующие детали:

Таблицы всегда содержат

Важный «особый случай» – работа с таблицами. По стандарту DOM у них должен быть , но в HTML их можно написать (официально) без него. В этом случае браузер добавляет в DOM самостоятельно.

Для такого HTML:

DOM-структура будет такой:

Видите? Из пустоты появился , как будто документ и был таким. Важно знать об этом, иначе при работе с таблицами возможны сюрпризы.

Другие типы узлов

Есть и некоторые другие типы узлов, кроме элементов и текстовых узлов.

Здесь мы видим узел нового типа – комментарий, обозначенный как #comment , между двумя текстовыми узлами.

Казалось бы – зачем комментарий в DOM? Он никак не влияет на визуальное отображение. Но есть важное правило: если что-то есть в HTML, то оно должно быть в DOM-дереве.

Все, что есть в HTML, даже комментарии, является частью DOM.

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

Даже объект document , представляющий весь документ, формально является DOM-узлом.

Существует 12 типов узлов. Но на практике мы в основном работаем с 4 из них:

  1. document – «входная точка» в DOM.
  2. узлы-элементы – HTML-теги, основные строительные блоки.
  3. текстовые узлы – содержат текст.
  4. комментарии – иногда в них можно включить информацию, которая не будет показана, но доступна в DOM для чтения JS.

Поэкспериментируйте сами

Чтобы посмотреть структуру DOM в реальном времени, попробуйте Live DOM Viewer. Просто введите что-нибудь в поле, и ниже вы увидите, как меняется DOM.

Другой способ исследовать DOM – это использовать инструменты разработчика браузера. Это то, что мы каждый день делаем при разработке.

Для этого откройте страницу elks.html, включите инструменты разработчика и перейдите на вкладку Elements.

Выглядит примерно так:

Вы можете увидеть DOM, понажимать на элементы, детально рассмотреть их и так далее.

Обратите внимание, что структура DOM в инструментах разработчика отображается в упрощённом виде. Текстовые узлы показаны как простой текст. И кроме пробелов нет никаких «пустых» текстовых узлов. Ну и отлично, потому что большую часть времени нас будут интересовать узлы-элементы.

Клик по этой кнопке в левом верхнем углу инспектора позволяет при помощи мыши (или другого устройства ввода) выбрать элемент на веб-странице и «проинспектировать» его (браузер сам найдёт и отметит его во вкладке Elements). Этот способ отлично подходит, когда у нас огромная HTML-страница (и соответствующий ей огромный DOM), и мы хотим увидеть, где находится интересующий нас элемент.

Есть и другой способ сделать это: можно кликнуть на странице по элементу правой кнопкой мыши и в контекстном меню выбрать «Inspect».

В правой части инструментов разработчика находятся следующие подразделы:

  • Styles – здесь мы видим CSS, применённый к текущему элементу: правило за правилом, включая встроенные стили (выделены серым). Почти всё можно отредактировать на месте, включая размеры, внешние и внутренние отступы.
  • Computed – здесь мы видим итоговые CSS-свойства элемента, которые он приобрёл в результате применения всего каскада стилей (в том числе унаследованные свойства и т.д.).
  • Event Listeners – в этом разделе мы видим обработчики событий, привязанные к DOM-элементам (мы поговорим о них в следующей части учебника).
  • … и т.д.

Лучший способ изучить инструменты разработчика – это прокликать их. Большинство значений можно менять и тут же смотреть результат.

Взаимодействие с консолью

При работе с DOM нам часто требуется применить к нему JavaScript. Например: получить узел и запустить какой-нибудь код для его изменения, чтобы посмотреть результат. Вот несколько подсказок, как перемещаться между вкладками Elements и Console.

  1. На вкладке Elements выберите первый элемент
  2. .
  3. Нажмите Esc – прямо под вкладкой Elements откроется Console.

Последний элемент, выбранный во вкладке Elements, доступен в консоли как $0 ; предыдущий, выбранный до него, как $1 и т.д.

Теперь мы можем запускать на них команды. Например $0.style.background = ‘red’ сделает выбранный элемент красным, как здесь:

Это мы посмотрели как получить узел из Elements в Console.

Есть и обратный путь: если есть переменная node , ссылающаяся на DOM-узел, можно использовать в консоли команду inspect(node) , чтобы увидеть этот элемент во вкладке Elements.

Или мы можем просто вывести DOM-узел в консоль и исследовать «на месте», как document.body ниже:

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

Инструменты разработчика браузера отлично помогают в разработке: мы можем исследовать DOM, пробовать с ним что-то делать и смотреть, что идёт не так.

Итого

HTML/XML документы представлены в браузере в виде DOM-дерева.

  • Теги становятся узлами-элементами и формируют структуру документа.
  • Текст становится текстовыми узлами.
  • … и т.д. Всё, что записано в HTML, есть и в DOM-дереве, даже комментарии.

Для изменения элементов или проверки DOM-дерева мы можем использовать инструменты разработчика в браузере.

Здесь мы рассмотрели основы, наиболее часто используемые и важные действия для начала разработки. Подробную документацию по инструментам разработки Chrome Developer Tools можно найти на странице https://developers.google.com/web/tools/chrome-devtools. Лучший способ изучить инструменты – походить по разным вкладкам, почитать меню: большинство действий очевидны для пользователя. Позже, когда вы немного их изучите, прочитайте документацию и узнайте то, что осталось.

У DOM-узлов есть свойства и методы, которые позволяют выбирать любой из элементов, изменять, перемещать их на странице и многое другое. Мы вернёмся к ним в последующих разделах.

Атрибуты и DOM-свойства

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/dom-attributes-and-properties.

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

Например, если тег выглядит как , то у объекта будет свойство body.id = «page» .

Но это преобразование – не один-в-один. Бывают ситуации, когда атрибут имеет одно значение, а свойство – другое. Бывает и так, что атрибут есть, а свойства с таким названием не создаётся.

Если коротко – HTML-атрибуты и DOM-свойства обычно, но не всегда соответствуют друг другу, нужно понимать, что такое свойство и что такое атрибут, чтобы работать с ними правильно.

Свои DOM-свойства

Ранее мы видели некоторые встроенные свойства DOM-узлов. Но, технически, никто нас ими не ограничивает.

Узел DOM – это объект, поэтому, как и любой объект в JavaScript, он может содержать пользовательские свойства и методы.

Например, создадим в document.body новое свойство и запишем в него объект:

document.body.myData = < name: 'Пётр', familyName: 'Петрович' >; alert( document.body.myData.name ); // Пётр

Можно добавить и новую функцию:

document.body.sayHi = function() < alert( this.nodeName ); >document.body.sayHi(); // BODY, выполнилась с правильным this

Нестандартные свойства и методы видны только в JavaScript и никак не влияют на отображение соответствующего тега.

Обратим внимание, пользовательские DOM-свойства:

  • Могут иметь любое значение.
  • Названия свойств чувствительны к регистру.
  • Работают за счёт того, что DOM-узлы являются объектами JavaScript.

Атрибуты

Элементам DOM, с другой стороны, соответствуют HTML-теги, у которых есть текстовые атрибуты.

Конечно, здесь речь именно об узлах-элементах, не о текстовых узлах или комментариях.

Доступ к атрибутам осуществляется при помощи стандартных методов:

  • elem.hasAttribute(name) – проверяет наличие атрибута
  • elem.getAttribute(name) – получает значение атрибута
  • elem.setAttribute(name, value) – устанавливает атрибут
  • elem.removeAttribute(name) – удаляет атрибут

Эти методы работают со значением, которое находится в HTML.

Также все атрибуты элемента можно получить с помощью свойства elem.attributes , которое содержит псевдо-массив объектов типа Attr.

В отличие от свойств, атрибуты:

  • Всегда являются строками.
  • Их имя нечувствительно к регистру (ведь это HTML)
  • Видны в innerHTML (за исключением старых IE)

Рассмотрим отличия между DOM-свойствами и атрибутами на примере HTML-кода:

Пример ниже устанавливает атрибуты и демонстрирует их особенности.

  alert( elem.getAttribute('About') ); // (1) 'Elephant', атрибут получен elem.setAttribute('Test', 123); // (2) атрибут Test установлен alert( document.body.innerHTML ); // (3) в HTML видны все атрибуты! var attrs = elem.attributes; // (4) можно получить коллекцию атрибутов for (var i = 0; i 

При запуске кода выше обратите внимание:

  1. getAttribute(‘About’) – первая буква имени атрибута About написана в верхнем регистре, а в HTML – в нижнем, но это не имеет значения, так как имена нечувствительны к регистру.
  2. Мы можем записать в атрибут любое значение, но оно будет превращено в строку. Объекты также будут автоматически преобразованы.
  3. После добавления атрибута его можно увидеть в innerHTML элемента.
  4. Коллекция attributes содержит все атрибуты в виде объектов со свойствами name и value .

Когда полезен доступ к атрибутам?

Когда браузер читает HTML и создаёт DOM-модель, то он создаёт свойства для всех стандартных атрибутов.

Например, свойства тега ‘A’ описаны в спецификации DOM: HTMLAnchorElement.

Например, у него есть свойство «href» . Кроме того, он имеет «id» и другие свойства, общие для всех элементов, которые описаны в спецификации в HTMLElement.

Все стандартные свойства DOM синхронизируются с атрибутами, однако не всегда такая синхронизация происходит 1-в-1, поэтому иногда нам нужно значение именно из HTML, то есть атрибут.

Рассмотрим несколько примеров.

Ссылка «как есть» из атрибута href

Синхронизация не гарантирует одинакового значения в атрибуте и свойстве.

Для примера, посмотрим, что произойдёт с атрибутом «href» при изменении свойства:

   

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

Стало быть, если мы хотим именно то, что в HTML, то нужно обращаться через атрибут.

Есть и другие подобные атрибуты

Кстати, есть и другие атрибуты, которые не копируются в точности. Например, DOM-свойство input.checked имеет логическое значение true/false , а HTML-атрибут checked – любое строковое, важно лишь его наличие.

Работа с checked через атрибут и свойство:

   

То есть, изменение DOM-свойства value на атрибут не влияет, он остаётся таким же.

А вот изменение атрибута обновляет свойство:

    

Эту особенность можно красиво использовать.

Получается, что атрибут input.getAttribute('value') хранит оригинальное (исходное) значение даже после того, как пользователь заполнил поле и свойство изменилось.

Например, можно взять изначальное значение из атрибута и сравнить со свойством, чтобы узнать, изменилось ли значение. А при необходимости и перезаписать свойство атрибутом, отменив изменения.

Классы в виде строки: className

Атрибуту "class" соответствует свойство className .

Так как слово "class" является зарезервированным словом в JavaScript, то при проектировании DOM решили, что соответствующее свойство будет называться className .

   

Кстати, есть и другие атрибуты, которые называются иначе, чем свойство. Например, атрибуту for ( ) соответствует свойство с названием htmlFor .

Классы в виде объекта: classList

Атрибут class – уникален. Ему соответствует аж целых два свойства!

Работать с классами как со строкой неудобно. Поэтому, кроме className , в современных браузерах есть свойство classList .

Свойство classList – это объект для работы с классами.

Оно поддерживается в IE начиная с IE10, но его можно эмулировать в IE8+, подключив мини-библиотеку classList.js.

  • elem.classList.contains("class") – возвращает true/false , в зависимости от того, есть ли у элемента класс class .
  • elem.classList.add/remove("class") – добавляет/удаляет класс class
  • elem.classList.toggle("class") – если класса class нет, добавляет его, если есть – удаляет.

Кроме того, можно перебрать классы через for , так как classList – это псевдо-массив.

   

Нестандартные атрибуты

У каждого элемента есть некоторый набор стандартных свойств, например для это будут href , name , а для это будут src , alt , и так далее.

Точный набор свойств описан в стандарте, обычно мы более-менее представляем, если пользуемся HTML, какие свойства могут быть, а какие – нет.

Для нестандартных атрибутов DOM-свойство не создаётся.

Свойство является стандартным, только если оно описано в стандарте именно для этого элемента.

То есть, если назначить элементу атрибут href , то свойство img.href от этого не появится. Как, впрочем, и если назначить ссылке атрибут alt :

   

Нестандартные атрибуты иногда используют для CSS.

В примере ниже для показа «состояния заказа» используется атрибут order-state :

 .order[order-state="new"] < color: green; >.order[order-state="pending"] < color: blue; >.order[order-state="canceled"] 
Новый заказ.
Ожидающий заказ.
Заказ отменён.

Почему именно атрибут? Разве нельзя было сделать классы .order-state-new , .order-state-pending , order-state-canceled ?

Конечно можно, но манипулировать атрибутом из JavaScript гораздо проще.

Например, если нужно отменить заказ, неважно в каком он состоянии сейчас – это сделает код:

div.setAttribute('order-state', 'canceled');

Для классов – нужно знать, какой класс у заказа сейчас. И тогда мы можем снять старый класс, и поставить новый:

div.classList.remove('order-state-new'); div.classList.add('order-state-canceled');

…То есть, требуется больше исходной информации и надо написать больше букв. Это менее удобно.

Проще говоря, значение атрибута – произвольная строка, значение класса – это «есть» или «нет», поэтому естественно, что атрибуты «мощнее» и бывают удобнее классов как в JS так и в CSS.

Свойство dataset, data-атрибуты

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

Как правило, это делается при помощи атрибутов с названиями, начинающимися на data- , например:

 
По улице прошёлся слон. Весьма красив и толст был он.

Стандарт HTML5 специально разрешает атрибуты data-* и резервирует их для пользовательских данных.

При этом во всех браузерах, кроме IE10-, к таким атрибутам можно обратиться не только как к атрибутам, но и как к свойствам, при помощи специального свойства dataset :

 
По улице прошёлся слон. Весьма красив и толст был он.

Обратим внимание – название data-user-location трансформировалось в dataset.userLocation . Дефис превращается в большую букву.

Полифил для атрибута hidden

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

Этот атрибут должен прятать элемент, действие весьма простое, для его поддержки в HTML достаточно такого CSS:

 [hidden] 
Текст

Если запустить в IE11- пример выше, то будет скрыт, а вот последний div , которому поставили свойство hidden в JavaScript – по-прежнему виден.

Это потому что CSS «не видит» присвоенное свойство, нужно синхронизировать его в атрибут.

Вот так – уже работает:

 [hidden]  
Текст

«Особенности» IE8

Если вам нужна поддержка этих версий IE – есть пара нюансов.

    Во-первых, версии IE8- синхронизируют все свойства и атрибуты, а не только стандартные:

document.body.setAttribute('my', 123); alert( document.body.my ); // 123 в IE8-

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

Итого

  • Атрибуты – это то, что написано в HTML.
  • Свойство – это то, что находится внутри DOM-объекта.

Таблица сравнений для атрибутов и свойств:

Свойства Атрибуты
Любое значение Строка
Названия регистрозависимы Не чувствительны к регистру
Не видны в innerHTML Видны в innerHTML

Синхронизация между атрибутами и свойствами:

  • Стандартные свойства и атрибуты синхронизируются: установка атрибута автоматически ставит свойство DOM. Некоторые свойства синхронизируются в обе стороны.
  • Бывает так, что свойство не совсем соответствует атрибуту. Например, «логические» свойства вроде checked , selected всегда имеют значение true/false , а в атрибут можно записать произвольную строку.Выше мы видели другие примеры на эту тему, например href .
  • Нестандартный атрибут (если забыть глюки старых IE) никогда не попадёт в свойство, так что для кросс-браузерного доступа к нему нужно обязательно использовать getAttribute .
  • Атрибуты, название которых начинается с data- , можно прочитать через dataset . Эта возможность не поддерживается IE10-.

Для того, чтобы избежать проблем со старыми IE, а также для более короткого и понятного кода старайтесь везде использовать свойства, а атрибуты – только там, где это действительно нужно.

А действительно нужны атрибуты очень редко – лишь в следующих трёх случаях:

  1. Когда нужно кросс-браузерно получить нестандартный HTML-атрибут.
  2. Когда нужно получить «оригинальное значение» стандартного HTML-атрибута, например, .
  3. Когда нужно получить список всех атрибутов, включая пользовательские. Для этого используется коллекция attributes .

Если вы хотите использовать собственные атрибуты в HTML, то помните, что атрибуты с именем, начинающимся на data- валидны в HTML5 и современные браузеры поддерживают доступ к ним через свойство dataset .

Задачи

Поставьте класс ссылкам

важность: 3

Сделайте жёлтыми внешние ссылки, добавив им класс external .

Руководство по DOM

Объектная Модель Документа (DOM) является программным интерфейсом для HTML, XML и SVG документов. Это обеспечивает структурированное представление документа (дерева), и определяет способ, по которому структура может быть доступна для программы, для изменения структуры документа, его стиля и содержания. DOM обеспечивает представление документа в виде структурированной группы узлов и объектов, которые имеют свойства и методы. По сути, она связывает веб -страницы со скриптами или языками программирования.

DOM чаще всего используется в JavaScript, но не является его частью, поэтому иногда с DOM работают в других языках.

DOM интерфейсы

  • Attr
  • CharacterData
  • ChildNode Экспериментальная возможность
  • Comment
  • CustomEvent (en-US)
  • Document
  • DocumentFragment
  • DocumentType (en-US)
  • DOMError (en-US)
  • DOMException (en-US)
  • DOMImplementation
  • DOMString
  • DOMTimeStamp (en-US)
  • DOMSettableTokenList
  • DOMStringList
  • DOMTokenList
  • Element
  • Event
  • EventTarget
  • HTMLCollection
  • MutationObserver
  • MutationRecord (en-US)
  • Node
  • NodeFilter (en-US)
  • NodeIterator (en-US)
  • NodeList
  • ParentNode Экспериментальная возможность
  • ProcessingInstruction (en-US)
  • Promise (en-US) Экспериментальная возможность
  • PromiseResolver (en-US) Экспериментальная возможность
  • Range
  • Text
  • TreeWalker (en-US)
  • URL
  • Window
  • Worker
  • XMLDocument Экспериментальная возможность

Устаревшие интерфейсы

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

  • CDATASection
  • DOMConfiguration
  • DOMErrorHandler
  • DOMImplementationList
  • DOMImplementationRegistry
  • DOMImplementationSource
  • DOMLocator
  • DOMObject
  • DOMUserData
  • Entity
  • EntityReference
  • NamedNodeMap
  • NameList
  • Notation
  • TypeInfo
  • UserDataHandler

HTML интерфейсы

Документ, содержащий HTML описывается с помощью HTMLDocument интерфейса. Обратите внимание, что HTML спецификация также расширяет Document интерфейс.

Объект HTMLDocument также даёт доступ к следующим возможностям браузера: вкладки, окна, в которых отрисовывается страница, используя интерфейс Window , ассоциированный с ним Style (обычно CSS), история браузера, относящаяся к контексту, History , в конце концов, Selection (en-US) в документе.

Интерфейсы HTML-элементов

  • HTMLAnchorElement
  • HTMLAppletElement
  • HTMLAreaElement
  • HTMLAudioElement
  • HTMLBaseElement
  • HTMLBodyElement
  • HTMLBRElement
  • HTMLButtonElement
  • HTMLCanvasElement
  • HTMLDataElement
  • HTMLDataListElement (en-US)
  • HTMLDirectoryElement
  • HTMLDivElement
  • HTMLDListElement (en-US)
  • HTMLElement
  • HTMLEmbedElement (en-US)
  • HTMLFieldSetElement (en-US)
  • HTMLFontElement (en-US)
  • HTMLFormElement (en-US)
  • HTMLFrameElement
  • HTMLFrameSetElement (en-US)
  • HTMLHeadElement
  • HTMLHeadingElement
  • HTMLHtmlElement (en-US)
  • HTMLHRElement (en-US)
  • HTMLIFrameElement (en-US)
  • HTMLImageElement
  • HTMLInputElement (en-US)
  • HTMLKeygenElement
  • HTMLLabelElement (en-US)
  • HTMLLegendElement (en-US)
  • HTMLLIElement (en-US)
  • HTMLLinkElement
  • HTMLMapElement (en-US)
  • HTMLMediaElement
  • HTMLMenuElement (en-US)
  • HTMLMetaElement (en-US)
  • HTMLMeterElement (en-US)
  • HTMLModElement (en-US)
  • HTMLObjectElement (en-US)
  • HTMLOListElement (en-US)
  • HTMLOptGroupElement (en-US)
  • HTMLOptionElement (en-US)
  • HTMLOutputElement (en-US)
  • HTMLParagraphElement (en-US)
  • HTMLParamElement (en-US)
  • HTMLPreElement (en-US)
  • HTMLProgressElement (en-US)
  • HTMLQuoteElement (en-US)
  • HTMLScriptElement
  • HTMLSelectElement (en-US)
  • HTMLSourceElement (en-US)
  • HTMLSpanElement (en-US)
  • HTMLStyleElement (en-US)
  • HTMLTableElement
  • HTMLTableCaptionElement (en-US)
  • HTMLTableCellElement (en-US)
  • HTMLTableDataCellElement (en-US)
  • HTMLTableHeaderCellElement (en-US)
  • HTMLTableColElement (en-US)
  • HTMLTableRowElement (en-US)
  • HTMLTableSectionElement (en-US)
  • HTMLTextAreaElement (en-US)
  • HTMLTimeElement
  • HTMLTitleElement (en-US)
  • HTMLTrackElement
  • HTMLUListElement (en-US)
  • HTMLUnknownElement
  • HTMLVideoElement

Другие интерфейсы

  • CanvasRenderingContext2D
  • CanvasGradient
  • CanvasPattern
  • TextMetrics (en-US)
  • ImageData
  • CanvasPixelArray (en-US)
  • NotifyAudioAvailableEvent (en-US)
  • HTMLAllCollection (en-US)
  • HTMLFormControlsCollection (en-US)
  • HTMLOptionsCollection (en-US)
  • HTMLPropertiesCollection
  • DOMStringMap
  • RadioNodeList (en-US)
  • MediaError

Устаревшие HTML интерфейсы

SVG интерфейсы

Интерфейсы SVG элементов

  • SVGAElement
  • SVGAltGlyphElement
  • SVGAltGlyphDefElement
  • SVGAltGlyphItemElement
  • SVGAnimationElement (en-US)
  • SVGAnimateElement (en-US)
  • SVGAnimateColorElement (en-US)
  • SVGAnimateMotionElement (en-US)
  • SVGAnimateTransformElement (en-US)
  • SVGCircleElement (en-US)
  • SVGClipPathElement (en-US)
  • SVGColorProfileElement
  • SVGComponentTransferFunctionElement (en-US)
  • SVGCursorElement (en-US)
  • SVGDefsElement (en-US)
  • SVGDescElement (en-US)
  • SVGElement (en-US)
  • SVGEllipseElement (en-US)
  • SVGFEBlendElement (en-US)
  • SVGFEColorMatrixElement (en-US)
  • SVGFEComponentTransferElement (en-US)
  • SVGFECompositeElement (en-US)
  • SVGFEConvolveMatrixElement (en-US)
  • SVGFEDiffuseLightingElement (en-US)
  • SVGFEDisplacementMapElement (en-US)
  • SVGFEDistantLightElement (en-US)
  • SVGFEFloodElement (en-US)
  • SVGFEGaussianBlurElement (en-US)
  • SVGFEImageElement (en-US)
  • SVGFEMergeElement (en-US)
  • SVGFEMergeNodeElement (en-US)
  • SVGFEMorphologyElement (en-US)
  • SVGFEOffsetElement (en-US)
  • SVGFEPointLightElement (en-US)
  • SVGFESpecularLightingElement (en-US)
  • SVGFESpotLightElement (en-US)
  • SVGFETileElement (en-US)
  • SVGFETurbulenceElement (en-US)
  • SVGFEFuncRElement (en-US)
  • SVGFEFuncGElement (en-US)
  • SVGFEFuncBElement (en-US)
  • SVGFEFuncAElement (en-US)
  • SVGFilterElement (en-US)
  • SVGFilterPrimitiveStandardAttributes
  • SVGFontElement (en-US)
  • SVGFontFaceElement (en-US)
  • SVGFontFaceFormatElement (en-US)
  • SVGFontFaceNameElement (en-US)
  • SVGFontFaceSrcElement (en-US)
  • SVGFontFaceUriElement (en-US)
  • SVGForeignObjectElement (en-US)
  • SVGGElement (en-US)
  • SVGGlyphElement (en-US)
  • SVGGlyphRefElement (en-US)
  • SVGGradientElement (en-US)
  • SVGHKernElement (en-US)
  • SVGImageElement (en-US)
  • SVGLinearGradientElement (en-US)
  • SVGLineElement (en-US)
  • SVGMarkerElement (en-US)
  • SVGMaskElement (en-US)
  • SVGMetadataElement (en-US)
  • SVGMissingGlyphElement (en-US)
  • SVGMPathElement (en-US)
  • SVGPathElement (en-US)
  • SVGPatternElement (en-US)
  • SVGPolylineElement (en-US)
  • SVGPolygonElement (en-US)
  • SVGRadialGradientElement (en-US)
  • SVGRectElement (en-US)
  • SVGScriptElement (en-US)
  • SVGSetElement (en-US)
  • SVGStopElement (en-US)
  • SVGStyleElement (en-US)
  • SVGSVGElement (en-US)
  • SVGSwitchElement (en-US)
  • SVGSymbolElement (en-US)
  • SVGTextElement
  • SVGTextPathElement (en-US)
  • SVGTitleElement (en-US)
  • SVGTRefElement (en-US)
  • SVGTSpanElement (en-US)
  • SVGUseElement (en-US)
  • SVGViewElement (en-US)
  • SVGVKernElement (en-US)

Интерфейсы SVG данных

DOM API для типов данных, используемых в определениях SVG свойств и атрибутов.

Примечание: Начиная с Gecko 5.0, следующие относящиеся к SVG DOM интерфейсы, представляя списки объектов, индексируются и к ним можно иметь доступ как к массивам; к тому же, у них есть свойство длины, обозначающее количество элементов в списках: SVGLengthList (en-US), SVGNumberList (en-US), SVGPathSegList и SVGPointList (en-US).

Статический тип
Анимированный тип
  • SVGAnimatedAngle (en-US)
  • SVGAnimatedBoolean (en-US)
  • SVGAnimatedEnumeration (en-US)
  • SVGAnimatedInteger (en-US)
  • SVGAnimatedLength (en-US)
  • SVGAnimatedLengthList (en-US)
  • SVGAnimatedNumber (en-US)
  • SVGAnimatedNumberList (en-US)
  • SVGAnimatedPreserveAspectRatio (en-US)
  • SVGAnimatedRect (en-US)
  • SVGAnimatedString (en-US)
  • SVGAnimatedTransformList (en-US)

Относящиеся к SMIL

Другие SVG интерфейсы

  • SVGAnimatedPathData
  • SVGAnimatedPoints (en-US)
  • SVGColorProfileRule
  • SVGCSSRule
  • SVGExternalResourcesRequired
  • SVGFitToViewBox
  • SVGLangSpace
  • SVGLocatable
  • SVGRenderingIntent (en-US)
  • SVGStylable (en-US)
  • SVGTests
  • SVGTextContentElement
  • SVGTextPositioningElement (en-US)
  • SVGTransformable
  • SVGUnitTypes (en-US)
  • SVGURIReference (en-US)
  • SVGViewSpec
  • SVGZoomAndPan

Смотрите также

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 19 нояб. 2023 г. by MDN contributors.

Your blueprint for a better internet.

MDN

Support

  • Product help
  • Report an issue

Our communities

Developers

  • Web Technologies
  • Learn Web Development
  • MDN Plus
  • Hacks Blog
  • Website Privacy Notice
  • Cookies
  • Legal
  • Community Participation Guidelines

Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.

Управление документами

При написании веб-страниц и приложений вам придётся часто каким-либо образом управлять структурой документа. Обычно это делается с помощью Document Object Model (DOM), набора API для управления разметкой HTML и стилями, которая сильно использует объект Document . В этой статье мы подробно рассмотрим, как использовать DOM и некоторые другие интересные API, которые могут изменить вашу среду интересными способами.

Предпосылки: Базовая компьютерная грамотность, базовое понимание HTML, CSS и JavaScript - включая объекты JavaScript.
Задача: Познакомиться с основными DOM API и другими API, обычно связанными с DOM, и манипулированием документами

Важные элементы веб-браузера

Веб-браузеры - очень сложные части программного обеспечения с множеством движущихся частей, многие из которых не могут контролироваться или управляться веб-разработчиком с использованием JavaScript. Вы можете подумать, что такие ограничения - это плохо, но браузеры заблокированы по уважительным причинам (в основном ради безопасности). Представьте себе, что веб-сайт может получить доступ к вашим сохранённым паролям или другой конфиденциальной информации и войти на веб-сайты так, как если бы это были вы?

Несмотря на ограничения, Web API по-прежнему дают нам доступ к множеству функциональных возможностей, которые позволяют нам многое делать с веб-страницами. Есть несколько действительно очевидных моментов, на которые вы будете регулярно ссылаться в своём коде. Рассмотрим следующую диаграмму, которая представляет основные части браузера, непосредственно участвующие в просмотре веб-страниц:

  • Окно - это вкладка браузера, в которую загружается веб-страница; это представлено в JavaScript объектом Window . Используя методы, доступные для этого объекта, вы можете делать такие вещи, как возврат размера окна (см. Window.innerWidth (en-US) и Window.innerHeight ), манипулировать документом, загруженным в этот window, хранить данные, специфичные для этого документа на стороне клиента (например, используя локальную базу данных или другой механизм хранения), присоединить обработчик событий (event handler) к текущему окну и многое другое.
  • Навигатор представляет состояние и идентификатор браузера (т. е. пользовательский агент), как он существует в Интернете. В JavaScript это представлено объектом Navigator . Вы можете использовать этот объект для извлечения таких вещей, как геолокационная информация, предпочтительный язык пользователя, медиапоток с веб-камеры пользователя и т. д.
  • Документ (представленный DOM в браузерах) представляет собой фактическую страницу, загруженную в окно, и представлен в JavaScript объектом Document . Вы можете использовать этот объект для возврата и обработки информации о HTML и CSS, содержащей документ, например, получить ссылку на элемент в DOM, изменить его текстовый контент, применить к нему новые стили, создать новые элементы и добавить их в текущий элемент как дочерний элемент, или даже вообще удалить его.

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

Объектная модель документа

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

Мы создали простую страницу примера в dom-example.html (см. также live). Попробуйте открыть это в своём браузере - это очень простая страница, содержащая элемент , внутри которого вы можете найти изображение и абзац со ссылкой внутри. Исходный код HTML выглядит так:

doctype html> html> head> meta charset="utf-8" /> title>Simple DOM exampletitle> head> body> section> img src="dinosaur.png" alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth." /> p> Here we will add a link to the a href="https://www.mozilla.org/">Mozilla homepagea> p> section> body> html> 

DOM, с другой стороны, выглядит так:

Примечание: . Эта диаграмма дерева DOM была создана с использованием Live DOM viewer Яна Хиксона.

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

  • Element node: элемент, как он существует в DOM.
  • Root node: верхний узел в дереве, который в случае HTML всегда является узлом HTML (другие словари разметки, такие как SVG и пользовательский XML, будут иметь разные корневые элементы)..
  • Child node: узел непосредственно внутри другого узла. Например, IMG является дочерним элементом SECTION в приведённом выше примере.
  • Descendant node (узел потомок): узел внутри дочернего элемента. Например, IMG является дочерним элементом SECTION в приведённом выше примере, и он также является потомком для родителя SECTION . IMG не является ребёнком BODY , так как он находится на двух уровнях ниже дерева в дереве, но он является потомком BODY .
  • Parent node: узел, в котором текущий узел. Например, BODY является родительским узлом SECTION в приведённом выше примере.
  • Sibling nodes (одноуровневый узел): узлы, которые расположены на одном уровне в дереве DOM. Например, IMG и P являются братьями и сёстрами в приведённом выше примере.
  • Text node: узел, содержащий текстовую строку.

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

Активное обучение: основы управления структурой DOM

Чтобы начать изучение по управлению структуры DOM, давайте начнём с практического примера.

  1. Возьмите локальную копию страницы dom-example.html page и изображение, которое вместе с ним.
  2. Добавьте элемент чуть выше закрывающего тега .
  3. Чтобы управлять элементом внутри DOM, вам сначала нужно выбрать его и сохранить ссылку на него внутри переменной. Внутри вашего скриптового элемента добавьте следующую строку:

let link = document.querySelector("a"); 
.textContent = "Mozilla Developer Network"; 
.href = "https://developer.mozilla.org"; 

Обратите внимание, что, как и во многих вещах в JavaScript, существует множество способов выбора элемента и хранения ссылки на него в переменной. Document.querySelector() - рекомендуемый современный подход, который считается удобным, потому что он позволяет вам выбирать элементы с помощью селекторов CSS. Вышеупомянутый запрос querySelector() будет соответствовать первому элементу , который появляется в документе. Если вы хотите совместить и делать что-то с несколькими элементами, вы можете использовать Document.querySelectorAll() , который соответствует каждому элементу документа, который соответствует селектору и сохраняет ссылки на них в массиве массива-подобном объекте, называемом NodeList.

Существуют более старые методы для захвата ссылок на элементы, например:

  • Document.getElementById() , который выбирает элемент с заданным значением атрибута id , например

    Мой абзац

    . Идентификатор передаётся функции как параметр, т.е. let elementRef = document.getElementById('myId') .

  • Document.getElementsByTagName() , который возвращает массив, содержащий все элементы на странице данного типа, например

    , и т.д. Тип элемента передаётся к функции в качестве параметра, то есть let elementRefArray = document.getElementsByTagName('p') .

Эти два работают в более старых браузерах, чем современные методы, такие как querySelector() , но не так удобны. Осмотритесь и вы увидите, что ещё можно найти!

Создание и размещение новых узлов

Вышесказанное дало вам немного представления о том, что вы можете сделать, но давайте продолжим и посмотрим, как мы можем создавать новые элементы.

let sect = document.querySelector("section"); 
let para = document.createElement("p"); para.textContent = "We hope you enjoyed the ride."; 
.appendChild(para); 
let text = document.createTextNode( " — the premier source for web development knowledge.", ); 
let linkPara = document.querySelector("p"); linkPara.appendChild(text); 

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

Перемещение и удаление элементов

Могут быть моменты, когда вы хотите переместить узлы или вообще удалить их из DOM. Это вполне возможно.

Если бы мы хотели переместить абзац со ссылкой внутри него в нижней части раздела, мы могли бы просто сделать это:

.appendChild(linkPara); 

Это переводит абзац вниз в нижнюю часть раздела. Вы могли подумать, что это сделает вторую копию, но это не так - linkPara - ссылка на единственную копию этого абзаца. Если вы хотите сделать копию и добавить её также, вам нужно будет использовать Node.cloneNode() .

Удаление узла довольно просто, по крайней мере, когда у вас есть ссылка на удаляемый узел и его родительский элемент. В нашем случае мы просто используем Node.removeChild() , например:

sect.removeChild(linkPara);

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

.parentNode.removeChild(linkPara); 

Попробуйте добавить вышеуказанные строки в свой код.

Управление стилями

Можно управлять стилями CSS с помощью JavaScript различными способами.

Для начала вы можете получить список всех таблиц стилей, прикреплённых к документу, с помощью Document.stylesheets (en-US), который возвращает массив объектов CSSStyleSheet . Затем вы можете добавлять / удалять стили по желанию. Однако мы не будем расширять эти функции, потому что они являются несколько архаичным и трудным способом манипулирования стилем. Есть гораздо более простые способы.

Первый способ - добавить встроенные стили непосредственно на элементы, которые вы хотите динамически стилизовать. Это делается с помощью свойства HTMLElement.style (en-US), которое содержит встроенную информацию о стиле для каждого элемента документа. Вы можете установить свойства этого объекта для непосредственного обновления стилей элементов.

    В качестве примера попробуйте добавить эти строки в наш текущий пример:

.style.color = "white"; para.style.backgroundColor = "black"; para.style.padding = "10px"; para.style.width = "250px"; para.style.textAlign = "center"; 
p style="color: white; background-color: black; padding: 10px; width: 250px; text-align: center;"> We hope you enjoyed the ride. p> 

Примечание: Примечание: Обратите внимание на то, как версии свойств JavaScript стилей CSS пишутся в нижнем регистре верблюжьего стиля (lower camel case), в то время как версии свойств стилей CSS используют дефисы (например, backgroundColor и background-color ). Убедитесь, что вы не перепутали их, иначе это не сработает.

Существует ещё один распространённый способ динамического управления стилями вашего документа, который мы рассмотрим сейчас.

  1. Удалите предыдущие пять строк, добавленных в JavaScript.
  2. Добавьте в свой HTML-код следующее: :

 .highlight
.setAttribute("class", "highlight"); 

Какой метод вы выбираете, зависит от вас; оба имеют свои преимущества и недостатки. Первый метод принимает меньше настроек и хорош для простого использования, тогда как второй метод более пурист (без смешивания CSS и JavaScript, без встроенных стилей, которые рассматриваются как плохая практика). Когда вы начнёте создавать более крупные приложения, вы, вероятно, начнёте использовать второй метод больше, но это действительно зависит от вас.

На данный момент мы не сделали ничего полезного! Нет смысла использовать JavaScript для создания статического контента - вы можете просто записать его в свой HTML и не использовать JavaScript. Это сложнее, чем HTML, и для создания вашего контента с помощью JavaScript также есть другие связанные с ним проблемы (например, не читаемые поисковыми системами).

В следующих параграфах мы рассмотрим ещё несколько практических применений DOM API.

Примечание: Примечание. Вы можете найти наш пример finished version of the dom-example.html на GitHub (см. также live).

Активное обучение: Получение полезной информации из объекта Window

До сих пор мы действительно смотрели на использование функций Node и Document для управления документами, но нет причин, по которым вы не можете получить данные из других источников и использовать его в пользовательском интерфейсе. Вспомните нашу простую демонстрацию maps-example.html из последней статьи - там мы извлекли некоторые данные о местоположении и использовали её для отображения карты вашей области. Вам просто нужно убедиться, что ваши данные в правильном формате; JavaScript упрощает работу, чем многие другие языки, будучи слабо типизированным - например, числа автоматически преобразуются в строки, когда вы хотите распечатать их на экране.

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

    Прежде всего, давайте возьмём ссылку на div, а затем возьмём ширину и высоту окна просмотра (внутреннее окно, где отображается ваш документ) и сохраните их в переменных - эти два значения удобно содержатся в Window.innerWidth (en-US) и Window.innerHeight . Добавьте следующие строки внутри существующего элемента :

let div = document.querySelector("div"); let WIDTH = window.innerWidth; let HEIGHT = window.innerHeight; 
.style.width = WIDTH + "px"; div.style.height = HEIGHT + "px"; 
.onresize = function ()  WIDTH = window.innerWidth; HEIGHT = window.innerHeight; div.style.width = WIDTH + "px"; div.style.height = HEIGHT + "px"; >; 

Примечание: . Если у вас возникла проблема, посмотрите на наш законченный пример изменения размера окна (см. также live).

Активное обучение: динамический список покупок

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

  • Элемент должен появиться в списке.
  • Каждому элементу должна быть предоставлена кнопка, которую можно нажать, чтобы удалить этот элемент из списка.
  • Вход должен быть опустошён и сфокусирован, чтобы вы могли ввести другой элемент.

Готовое демо будет выглядеть примерно так:

Чтобы завершить упражнение, выполните следующие действия и убедитесь, что список ведёт себя так, как описано выше.

  1. Для начала загрузите копию нашего начального файла shopping-list.html и скопируйте его где-нибудь. Вы увидите, что у него есть минимальный CSS, список с меткой, ввод и кнопка, пустой список и элемент . Вы будете делать все свои дополнения внутри скрипта.
  2. Создайте три переменные, содержащие ссылки на список ( , и элементы.
  3. Создайте function, которая будет запускаться в ответ на нажатие кнопки.
  4. Внутри тела функции начните с сохранения текущего значения (value (en-US)) входного элемента в переменной.
  5. Затем очистите элемент ввода, установив его значение в пустую строку — '' .
  6. Создайте три новых элемента - элемент списка ( ), и и сохраните их в переменных.
  7. Добавьте диапазон и кнопку в качестве дочерних элементов списка.
  8. Установите текстовое содержимое диапазона на значение входного элемента, которое вы сохранили ранее, и текстовое содержимое кнопки «Удалить».
  9. Добавить элемент списка в качестве дочернего списка.
  10. Прикрепите обработчик события к кнопке удаления, чтобы при щелчке удалял весь элемент списка, внутри которого он находится.
  11. Наконец, используйте метод focus() (en-US), чтобы сфокусировать входной элемент, готовый для входа в следующий элемент списка покупок.

Примечание: Примечание: Если у вас возникла действительно сложная проблема, взгляните на наши примеры finished shopping list (see it running live also.)

Краткая информация

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

Дополнительная информация

Есть много возможностей, которые можно использовать для управления вашими документами. Ознакомьтесь с некоторыми нашими рекомендациями и узнайте, что вы можете обнаружить:

(Полный список веб-индексов API, задокументированных MDN: Web API index)

В этот модуль входит

  • Introduction to web APIs
  • Manipulating documents
  • Fetching data from the server
  • Third party APIs
  • Drawing graphics (en-US)
  • Video and audio APIs (en-US)
  • Client-side storage

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 3 авг. 2023 г. by MDN contributors.

Your blueprint for a better internet.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *