Объектная модель документа( DOM)
Как видно из рисунка, на вершине стоит window.
У этого объекта двоякая позиция – он с одной стороны является глобальным объектом в JavaScript, с другой – содержит свойства и методы для управления окном браузера, открытия новых окон, например:
// открыть новое окно/вкладку с URL http://ya.ru window.open('http://ya.ru');
Объектная модель документа (DOM)
Глобальный объект document даёт возможность взаимодействовать с содержимым страницы.
Пример использования:
document.body.style.background = 'red'; alert( 'Элемент BODY стал красным, а сейчас обратно вернётся' ); document.body.style.background = '';
Он и его свойства и методы описаны в стандарте W3C DOM .
Работа с DOM
Для JavaScript веб-страница доступна в виде объектной модели документа (document object model) или сокращенно DOM. DOM описывает структуру веб-станицы в виде древовидного представления и предоставляет разработчикам способ получить доступ к веб-станице и ее отдельным элементам.
Например, рассмотрим простейшую страницу:
Page Title
Page Header
Block Header
Text
Все компоненты упорядочены в DOM иерархическим образом, где каждый компонент представляет отдельный узел. То есть каждый элемент, например, элемент div, представляет собой узел. Но также и текст внутри элемента представляет отдельный узел.
- Существует следующие виды узлов:
- Element - html-элемент
- Attr - атрибут html-элемента
- Document - корневой узел html-документа
- DocumentType - DTD или тип схемы XML-документа
- DocumentFragment - место для временного хранения частей документа
- EntityReference - ссылка на сущность XML-документа
ProcessingInstruction - инструкция обработки веб-страницы
Comment - элемент комментария
Text - текст элемента
CDATASection - секция CDATA в документе XML
Entity - необработанная сущность DTD
Notation - нотация, объявленная в DTD.
Несмотря на такое большое количество типов узлов, как правило, мы будем работать только с некоторыми из них .
Объект document. Поиск элементов
Для работы со структурой DOM в JavaScript предназначен объект , который определен в глобальном объекте . Объект document предоставляет ряд свойств и методов для управления элементами страницы.
Поиск элементов
Для поиска элементов на странице применяются следующие методы:
- getElementById(value) - выбирает элемент, у которого атрибут id равен value
- getElementsByTagName(value) - выбирает все элементы, у которых тег равен value
- getElementsByClassName(value) выбирает все элементы, которые имеют класс value
- querySelector(value) - выбирает первый элемент, который соответствует css-селектору value
- querySelectorAll(value) - выбирает все элементы, которые соответствуют css-селектору value.
Например, найдем элемент по id:
Block Header
Text
var headerElement = document.getElementById("header"); document.write("Текст заголовка: " + headerElement.innerText);
С помощью вызова document.getElementById("header")
находим элемент, у которого id="header". А с помощью свойства можно получить текст найденного элемента.
Поиск по определенному тегу:
Заголовок
Первый абзац
Второй абзац
var pElements = document.getElementsByTagName("p");
for (var i = 0; i
document.write("Текст параграфа: " + pElements[i].innerText + "
");
}
С помощью вызова
document.getElementsByTagName("p")
находим все элементы параграфов. Этот вызов возвращает массив найденных элементов. Поэтому, чтобы получить отдельные элементы массива, необходимо пробежаться по ним в цикле.
Заголовок статьи " width="640"
Если нам надо получить только первый элемент, то можно :
var pElement = document.getElementsByTagName("p")[0]; document.write("Текст параграфа: " + pElement.innerText);
Получение элемента по классу:
Заголовок статьи
Первый абзац
Второй абзац
var articleDiv = document.getElementsByClassName("article")[0];
console.log(articleDiv);
var textElems = document.getElementsByClassName("text");
for (var i = 0; i
console.log(textElems[i]);
}
Выбор по селектору css
Аннотация статьи
Первый абзац
Второй абзац
var elem = document.querySelector(".annotation p");
document.write("Текст селектора: " + elem.innerText);
Выражение
document.querySelector(".annotation p")
находит элемент, который соответствует селектору .annotation p. Если на странице несколько элементов, соответствующих селектору, то метод выберет первый из них. В итоге браузер выведет:
Аннотация статьи
Первый абзац
Второй абзац
Текст селектора:
Аннотация статьи
Чтобы получить все элементы по селектору, можно подобным образом использовать метод , который возвращает массив найденных элементов:
Аннотация статьи
Первый абзац
Второй абзац
var elems = document.querySelectorAll(".text p");
for (var i = 0; i
document.write("Текст селектора " + i + ": " + elems[i].innerText + "
");
}
Вывод браузера:
Аннотация статьи
Первый абзац
Второй абзац
Текст селектора 0: Первый абзац
Текст селектора 1: Второй абзац
Свойства объекта document
Кроме ранее рассмотренных методов объект document позволяет обратиться к определенным элементам веб-страницы через свойства:
- documentElement предоставляет доступ к корневому элементу
- body - предоставляет доступ к элементу на веб-странице
- Images - содержит коллекцию всех объектов изображений (элементов img)
- links - содержит коллекцию ссылок - элементов и , у которых определен атрибут href
- anchors - предоставляет доступ к коллекции элементов , у которых определен атрибут name
- forms - содержит коллекцию всех форм на веб-странице
.
Эти свойства не предоставляют доступ ко всем элементам, однако позволяют получить наиболее часто используемые элементы на веб-странице.
Например, получим корневой узел документа:
var container = document.documentElement;
Получим все изображения на странице:
var images = document.images;
// изменим первое изображение
images[0].src="pics/picture_4.jpg";
images[0].alt="Новая картинка";
// перебирем все изображения
for(var i=0; i
document.write("
" + images[i].src);
document.write("
" + images[i].alt);
}
Подобно тому, как в коде можно установить атрибуты у элемента img, так и в коде javascript мы можем через свойства src и alt получить и установить значения этих атрибутов.
Рассмотрим получение всех ссылок на странице:
Статья 1
Статья 2
Статья 3
var links = document.links;
for(var i=0; i
document.write("
" + links[i].innerText);
document.write("
" + links[i].href);
}
Так как у ссылки определен атрибут href , то при переборе ссылок мы можем получить его значение.
Объект Node. Навигация по DOM
Каждый отдельный узел в структуре DOM представлен объектом Node . Этот объект предоставляет ряд свойств, с помощью которых можно получить информацию о данном узле:
- childNodes содержит коллекцию дочерних узлов
- firstChild возвращает первый дочерний узел текущего узла
- lastChild возвращает последний дочерний узел текущего узла
- previousSibling возвращает предыдущий элемент, который находится на одном уровне с текущим
- nextSibling возвращает следующий элемент, который находится на одном уровне с текущим
- ownerDocument возвращает корневой узел документа
- parentNode возвращает элемент, который содержит текущий узел
- nodeName возвращает имя узла
- nodeType возвращает тип узла в виде числа
- nodeValue возвращает или устанавливает значение узла в виде простого текста
Пример . Требуется перебрать все дочерние узлы элемента:
Заголовок статьи
Первый абзац
Второй абзац
var articleDiv = document.querySelector("div.article");
var nodes = articleDiv.childNodes;
for(var i=0; i
var type = "";
if(nodes[i].nodeType===1)
type="элемент";
else if(nodes[i].nodeType===2)
type="атрибут";
else if(nodes[i].nodeType===3)
type="текст";
console.log(nodes[i].nodeName + ": " + type);
}
Метод document.querySelector("div.article") выбирает элемент div с классом article и пробегаемся по его дочерним узлам. И в цикле выводим имя узла и его тип с помощью свойств nodeName и nodeType. Каждому типу соответствует определенное число:
node Type Тип узла
1
элемент
2
атрибут
3
Текст
Но несмотря на то, что в блоке div на странице только три узла: h3 и 2 параграфа, но консоль отобразит нам пять узлов.
Заголовок статьиПервый абзацВторой абзац Но при переборе обнаруживается только три дочерних узла. Навигация по узлам Используя свойства nextSibling и previousSibling можно также пройтись по узлам в прямом или обратном порядке. Например, для прохода по элементам на той же станице можно использовать следующий код javascript: " width="640"
Это пототму, что пробелы между узлами также считаются за отдельные текстовые узлы. Если бы пробелов не было:
div class="article"
Заголовок статьи
Первый абзац
Второй абзац
Но при переборе обнаруживается только три дочерних узла.
Навигация по узлам
Используя свойства nextSibling и previousSibling можно также пройтись по узлам в прямом или обратном порядке.
Например, для прохода по элементам на той же станице можно использовать следующий код javascript:
var articleDiv = document.querySelector("div.article");
// получаем первый дочерний элемент
var node = articleDiv.firstChild;
console.log(node.nodeName);
// обращаемся к следующему узлу, пока он определен
while((node=node.nextSibling)!==null){
console.log(node.nodeName);
}
В цикле мы обращаемся к следующему узлу, который находится на одном уровне с текущим (или сестринскому узлу).
Также можно перебрать узлы в обратном порядке: сначала получаем последний узел, а затем обращаемся к предыдущему сестринскому узлу:
var articleDiv = document.querySelector("div.article");
// получаем первый дочерний элементvar node = articleDiv.lastChild;console.log(node.nodeName);
// обращаемся к предыдующему узлу, пока он определен
while((node=node.previousSibling)!==null){
console.log(node.nodeName);}
Создание, добавление и удаление элементов веб-страницы
Для создания элементов объект document имеет следующие методы:
- createElement(elementName) создает элемент html, тег которого передается в качестве параметра. Возвращает созданный элемент
- createTextNode(text) создает и возвращает текстовый узел. В качестве параметра передается текст узла.
var elem = document.createElement("div");
var elemText = document.createTextNode("Привет мир");
Переменная elem будет хранить ссылку на элемент div. Однако одного создания элементов недостаточно, их еще надо добавить на веб-страницу.
appendChild(newNode) добавляет новый узел newNode в конец коллекции дочерних узлов .
insertBefore(newNode, preferenceNode) добавляет новый узел newNode перед узлом referenceNode .
Используем метод appendChild :
Заголовок статьи
Первый абзац
Второй абзац
var articleDiv = document.querySelector("div.article");
// создаем элемент
var elem = document.createElement("h2");
// создаем для него текст
var elemText = document.createTextNode("Привет мир");
// добавляем текст в элемент в качестве дочернего элемента
elem.appendChild(elemText);
// добавляем элемент в блок div
articleDiv.appendChild(elem);
Сначала создаем обычный элемент заголовка h2 и текстовый узел. Затем текстовый узел добавляем в элемент заголовка. Затем заголовок добавляем в один из элементов веб-страницы:
Необязательно для определения текста внутри элемента создавать дополнительный текстовый узел, так как мы можем воспользоваться свойством и напрямую ему присвоить текст: