Создание и добавление элементов DOM
На этом занятии мы поговорим о том как можно добавлять и удалять элементы в DOM-дереве, то есть, фактически в HTML-документе. И начнем с такого примера. Предположим, мы хотим создать вот такое сообщение:
DOCTYPE html> html> head> title>Уроки по JavaScripttitle> head> style> .msg { width: 400px; margin: 0 auto; text-align: center; background: #20454B; padding: 5px; border-radius: 5px; color: #eee; font-size: 24px; } style> body> div class="msg">Важная информация!div> script> script> body> html>
Но будем это делать посредством JavaScript. Поэтому тег div уберем. Теперь, чтобы создать элемент div, воспользуемся методом
let div = document.createElement('div');
Далее, укажем класс стилей и содержимое:
div.className = "msg"; div.innerHTML = "Важная информация!";
Все, теперь переменная div является объектом для представления тега div с классом msg и строкой «Важная информация!». Но этот объект пока еще не является частью DOM-дерева, а значит, не содержится в HTML-документе. Если мы сейчас обновим страницу, то ничего на ней не увидим.
Для размещения объекта на HTML-странице существует несколько методов. Сейчас мы воспользуемся методом append, который может быть вызван из любого узла DOM-дерева для добавления объекта как дочернего в конец списка. Например, добавим наш div в раздел body:
И если теперь посмотрим структуру HTML-документа, то увидим, что div идет последним в списке дочерних элементов раздела body.
Кроме метода append существуют такие методы вставки:
- node.prepend(. nodes or strings) – вставляет узлы или строки в начало node;
- node.before(. nodes or strings) – вставляет узлы или строки до node;
- node.after(. nodes or strings) – вставляет узлы или строки после node;
- node.replaceWith(. nodes or strings) – заменяет node заданными узлами или строками.
Обратите внимание, что эти методы могут вставлять не только объекты-теги, но и текстовые элементы как строки. Чтобы все было понятнее, рассмотрим работу этих методов на таком примере. Пусть у нас имеется документ:
h1>Солнечная системаh1> ul> li>Солнце li>Меркурий li>Венера li>Земля ul>
let list = document.querySelector("ul"); list.before('before'); list.after('after');
let li_1 = document.createElement('li'); li_1.innerHTML = "первый элемент"; list.prepend(li_1); let li_2 = document.createElement('li'); li_2.innerHTML = "последний элемент"; list.append(li_2);
list.replaceWith(document.createElement("hr"), "замена", document.createElement("br"));
заменяет весь список новой информацией: тегом hr, строкой «замена» и тегом br. Вот этот последний пример показывает, что данные методы могут принимать сразу более одного аргумента для вставки нескольких элементов. Методы append/prepend/before/after позволяют также перемещать уже существующие элементы. То есть, когда мы вставляем имеющийся элемент, он автоматически удаляется со своего прежнего места и добавляется в новое. Например, у нас есть исходный список и мы хотим «солнце» поместить после «земли». Это можно сделать так:
let li = document.querySelector("ul.list > li:first-child"); let list = document.querySelector("ul.list"); list.append(li);
В JavaScript помимо создания элементов-тегов с помощью метода createElement можно создавать и текстовые элементы. Для этого следует использовать метод document.createTextNode(text) например, так:
let textNode = document.createTextNode('Текстовый элемент'); document.body.append(textNode);
insertAdjacentHTML
Рассмотренные выше методы вставки добавляют либо отдельные теги, либо текстовую информацию. Причем, текст вставляется именно как текст, то есть, теги внутри текста будут отображены как текст. Например:
document.body.append("Текст с тегом");
- «beforebegin» – для вставки html непосредственно перед elem;
- «afterbegin» – для вставки html как первого дочернего элемента в elem;
- «beforeend» – для вставки html как последнего дочернего элемента в elem;
- «afterend» – для вставки html непосредственно после elem.
ul> li>Меркурий li>Венера li>Земля ul>
Смотрите как разместились эти элементы. Существует еще два похожих метода, но более специализированных:
- insertAdjacentText(where, text) – для вставки строки текста text;
- insertAdjacentElement(where, elem) – для вставки элемента elem.
Например:
list.insertAdjacentText("beforebegin", "Список планет
");
let li = document.createElement("li"); li.innerHTML="Солнце"; list.insertAdjacentElement("afterbegin", li);
добавит соответствующий элемент. Однако, на практике эти два метода почти не применяются. Вместо них удобнее использовать методы append/prepend/before/after просто потому, что легче писать. Если нам нужно удалить какой-либо узел из DOM-дерева, то для этого часто используется метод node.remove() Например, имеется список:
ul class="list"> li>Солнце li>Меркурий li>Венера li>Земля li>Марс ul>
И мы из него хотим из него удалять последние пункты, пока полностью не очистим. Это можно сделать так:
let idRemove = setInterval(function() { let li = document.querySelector("ul.list > li:last-child"); if(li === null) { clearInterval(idRemove); alert("Список удален"); } else li.remove(); }, 500);
cloneNode
Следующий метод cloneNode позволяет создавать клон узла DOM-дерева. Он имеет следующий синтаксис: elem.cloneNode(flDeep); Если flDeep равен true, то создается «глубокий» клон объекта со всеми его свойствами и дочерними элементами. При значении false получаем клон без дочерних элементов. Когда может пригодиться такая операция. Например, у нас есть вот такая таблица:
table border=1 cellpadding="10"> tr>td>Солнцеtd>td>Звездаtd>tr> tr>td>Меркурийtd>td>Планетаtd>tr> table>
Мы хотим добавить в нее еще одну строку с планетой Венерой. Это можно сделать путем клонирования существующей строки и добавления клона в конец таблицы:
let t = document.querySelector("table"); let r = document.querySelector("table>tbody>tr:last-child"); let row = r.cloneNode(true); row.firstChild.innerHTML = "Венера"; t.append(row);
DocumentFragment
В JavaScript есть DOM-объект специального вида – DocumentFragment. Он как бы образует фрагмент документа со своим DOM-деревом, то есть, со своим содержимым. Затем, это содержимое можно целиком вставить в любое место HTML-документа. Приведем такой простой пример. Предположим, имеется пустой список:
let fr = new DocumentFragment(); let list=["Меркурий", "Венера", "Земля", "Марс"]; for(let p of list) { let item = document.createElement('li'); item.innerHTML = p; fr.append(item); } let ul = document.querySelector("ul"); ul.append(fr);
Но это лишь пример использования DocumentFragment. В данном конкретном случае все можно реализовать проще:
let list=["Меркурий", "Венера", "Земля", "Марс"]; let ul = document.querySelector("ul"); for(let p of list) { let item = document.createElement('li'); item.innerHTML = p; ul.append(item); }
- parent.appendChild(node) – добавляет элемент в конец списка дочерних элементов;
- parent.insertBefore(node, nextSibling) – вставляет элемент перед nextSibling;
- parent.removeChild(node) – удаляет элемент node (здесь parent является родителем node);
- parent.replaceChild(newElem, node) – заменяет дочерний элемент node на новый newElem.
document.write
Это довольно древний метод, который появился в JavaScript когда даже не было понятия DOM-объектов и DOM-дерева. Данный метод позволяет добавлять HTML-содержимое в то место, где записан и имеет такой синтаксис: document.write(html); Причем, срабатывает этот метод только в момент загрузки страницы. Если вызвать его после загрузки, то все содержимое HTML-документа будет удалено! В качестве примера приведу такую страницу:
h1>Солнечная системаh1> script> document.write('Строка вставленная методом write'
); script> ul> li>Солнце li>Меркурий li>Венера li>Земля ul>
setTimeout(function() { document.write('Строка вставленная методом write'); }, 500);
Видите? Все содержимое HTML-документа пропало и осталась только эта одна строка. Но, несмотря на все эти особенности, метод document.write иногда применяют для динамического формирования HTML-страницы. Дело в том, что он срабатывает еще до построения DOM-дерева и все что он добавит в документ воспринимается браузером так, словно такая страница изначально была получена с сервера. И, в частности, так можно динамически добавлять теги