Добавление и удаление узлов в DOM

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

Удаление узлов

removeChild()

Для удаления узлов используется метод removeChild().

parent.removeChild(узел)
узел
Ссылка на удаляемый узел.

Из названия видно, что данный метод удаляет дочерний узел. То есть метод removeChild() необходимо вызывать на том элементе, который является родительским для удаляемого узла.

Метод removeChild() возвращает ссылку на удалённый объект. С этим узлом впоследствии можно работать.

<html>
<head>
  <title>DOM интерфейс</title>
</head>
<body>
  <ul>
    <li>Lorem</li>
    <li>ipsum</li>
    <li>dolor</li>
  </ul>
</body>
</html>

<script>
  var list = document.querySelector('ul');
  alert(list.children.length); /* 3 */
  var removed = list.removeChild(list.children[0]); /* удаляем первый дочерний элемент списка */
  alert(list.children.length); /* 2 */
  alert(removed); /* [object HTMLLIElement], ссылка на удалённый элемент */
</script>

remove()

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

<html>
<head>
  <title>DOM интерфейс</title>
</head>
<body>
  <ul>
    <li>Lorem</li>
    <li>ipsum</li>
    <li>dolor</li>
  </ul>
</body>
</html>

<script>
  Element.prototype.remove = function() {
      return this.parentNode.removeChild(this);
  };
  var list_items = document.querySelectorAll('li');
  var removed = list_items[0].remove(); /* удаляем первый дочерний элемент списка */
  alert(removed.innerHTML); /* Lorem */
</script>

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

Новые узлы DOM модели создаются очень просто. Для этого используются встроенные методы объекта document.

document.createElement(тег)
Создаёт узел элемент. Аргументом указывается имя тега.
document.createTextNode(текст)
Создаёт текстовый узел. Аргументом указывается содержимое узла.
document.createComment(текст)
Создаёт узел комментарий. Аргументом указывается содержимое узла.
var elem = document.createElement('aside');
elem.innerHTML = 'Содержимое узла <aside>';
var text = document.createTextNode('Текстовый узел');
var comment = document.createComment('Комментарий');

Клонирование узлов

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

cloneNode()

Для клонирования узлов используется метод cloneNode().

element.cloneNode(глубина)
глубина
Булевое значение, которое указывает глубину клонирования. Если аргумент имеет значение true, то будет выполнено полное клонирование данного элемента - со всеми атрибутами и вложенными узлами. Если указать false, то элемент скопируется без дочерних узлов, но со всеми атрибутами. Данный аргумент необязательный, но его желательно указывать всегда, так как различные браузеры могут использовать разные значения по умолчанию.
<html>
<head>
  <title>DOM интерфейс</title>
</head>
<body>
  <p class="paragraph">Lorem ipsum dolor...</p>
</body>
</html>

<script>
  var par = document.querySelector('p');
  alert(par.cloneNode(true).outerHTML); /* <p class="paragraph">Lorem ipsum dolor...</p> */
  alert(par.cloneNode(false).outerHTML); /* <p class="paragraph"></p> */
</script>

Использование cloneNode() может привести к появлению в документе элементов с одинаковым уникальным идентификатором id или именем name.

Если исходный элемент имеет атрибут id или name, тогда перед вставкой в документ необходимо изменить эти атрибуты у элемента-клона.

Добавление узлов

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

Методы, добавляющие новые узлы в структуру документа, должны вызываться на том элементе, внутрь которого необходимо произвести вставку (то есть он будет родительским по отношению к вставляемому элементу).

appendChild()

Самый простой метод для вставки нового узла в документ - это appendChild(). Он вставляет новый узел в конец родительского элемента. Вставляемый узел становится последним в списке дочерних узлов элемента.

parent.appendChild(узел)
узел
Ссылка на вставляемый узел.
<html>
<head>
  <title>DOM интерфейс</title>
</head>
<body>
  <ul>
    <li>Lorem</li>
    <li>ipsum</li>
  </ul>
</body>
</html>

<script>
  var list = document.querySelector('ul');
  alert(list.lastElementChild.innerHTML); /* последний элемент - 'ipsum' */

  var list_item = document.createElement('li');
  list_item.innerHTML = 'dolor';
  list.appendChild(list_item); /* добавляем новый элемент */
  alert(list.lastElementChild.innerHTML); /* последний элемент - 'dolor' */
</script>

insertBefore()

Другой метод для добавления узла в документ - insertBefore().

parent.insertBefore(узел, место_вставки)
узел
Ссылка на вставляемый узел.
место_вставки
Ссылка на элемент, перед которым необходимо вставить новый узел. Если аргумент равен null, то узел вставляется в конец родителя (то есть сработает, как appendChild()).

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

Варианты применения:

// Вставка в самое начало родителя, то есть перед первым узлом
parent.insertBefore(element, parent.firstChild);
// Вставка в конец родителя, аналогично appendChild()
parent.insertBefore(element, null);
// Вставка перед конкретным элементом parentChild
parent.insertBefore(element, parentChild);
// Вставка после конкретного элемента parentChild
parent.insertBefore(element, parentChild.nextSibling);
// здесь происходит вставка перед тем узлом, который находится сразу за узлом parentChild

replaceChild()

Ещё один способ добавить элемент на страницу - воспользоваться методом replaceChild(). Он совмещает в себе сразу два действия: удаляет один узел и вставляет на его место новый.

parent.replaceChild(новый_узел, старый_узел)
новый_узел
Ссылка на вставляемый узел.
старый_узел
Ссылка на удаляемый узел.

Метод возвращает ссылку на удалённый узел.

<html>
<head>
  <title>DOM интерфейс</title>
</head>
<body>
  <ul>
    <li>Lorem</li>
    <li>ipsum</li>
  </ul>
</body>
</html>

<script>
  var list = document.querySelector('ul');
  var list_item = document.createElement('li');
  list_item.innerHTML = 'dolor';
  var removed = list.replaceChild(list_item, list.lastElementChild); /* заменяем последний элемент */
  alert(removed.innerHTML); /* ipsum */
</script>

insertAdjacentHTML()

Добавить новый узел в документ можно простой вставкой HTML-кода в виде строки. Для этого используется метод insertAdjacentHTML().

parent.insertAdjacentHTML(место_вставки, HTML_код)
место_вставки
Позиция, куда необходимо вставить код. Это место указывается относительно самого элемента и может иметь одно из следующих значений:
  • beforebegin - непосредственно перед открывающим тегом.
  • afterbegin - сразу после открывающего тега.
  • beforeend - непосредственно перед закрывающим тегом.
  • afterend - сразу после закрывающего тега.
<!--beforebegin--><p><!--afterbegin-->Hello<!--beforeend--></p><!--afterend-->
Для одинарного тега используются только beforebegin и afterend.
HTML_код
Строка с HTML-кодом.

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

<html>
<head>
  <title>DOM интерфейс</title>
</head>
<body>
  <ul>
    <li>Lorem</li>
    <li>ipsum</li>
  </ul>
</body>
</html>

<script>
  var list = document.querySelector('ul');
  alert(list.lastElementChild.innerHTML); /* последний элемент - 'ipsum' */

  list.insertAdjacentHTML('beforeend', '<li>dolor</li>'); /* добавляем новый элемент */
  alert(list.lastElementChild.innerHTML); /* последний элемент - 'dolor' */
</script>

Перемещение узлов

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

<html>
<head>
  <title>DOM интерфейс</title>
</head>
<body>
  <ul>
    <li>Lorem</li>
    <li>ipsum</li>
    <li>dolor</li>
  </ul>
</body>
</html>

<script>
  var list = document.querySelector('ul');
  list.insertBefore(list.lastElementChild, list.firstElementChild); /* перемещаем последний элемент в начало */
</script>

Для копирования элемента (а не перемещения) предварительно необходимо создать его клон с помощью метода cloneNode().