Удаление узлов
Для удаления узла есть методы node.remove()
.
Например, сделаем так, чтобы наше сообщение удалялось через секунду:
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<script>
let div = document.createElement('div');
div.className = "alert";
div.innerHTML = "<strong>Всем привет!</strong> Вы прочитали важное сообщение.";
document.body.append(div);
setTimeout(() => div.remove(), 1000);
</script>
Если нам нужно переместить элемент в другое место – нет необходимости удалять его со старого.
Все методы вставки автоматически удаляют узлы со старых мест.
Например, давайте поменяем местами элементы:
<div id="first">Первый</div>
<div id="second">Второй</div>
<script>
// нет необходимости вызывать метод remove
second.after(first); // берёт #second и после него вставляет #first
</script>
Клонирование узлов: cloneNode
Как вставить ещё одно подобное сообщение?
Мы могли бы создать функцию и поместить код туда. Альтернатива – клонировать существующий div
и изменить текст внутри него (при необходимости).
Иногда, когда у нас есть большой элемент, это может быть быстрее и проще.
- Вызов
elem.cloneNode(true)
создаёт «глубокий» клон элемента – со всеми атрибутами и дочерними элементами. Если мы вызовемelem.cloneNode(false)
, тогда клон будет без дочерних элементов.
Пример копирования сообщения:
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<div class="alert" id="div">
<strong>Всем привет!</strong> Вы прочитали важное сообщение.
</div>
<script>
let div2 = div.cloneNode(true); // клонировать сообщение
div2.querySelector('strong').innerHTML = 'Всем пока!'; // изменить клонированный элемент
div.after(div2); // показать клонированный элемент после существующего div
</script>
DocumentFragment
DocumentFragment
является специальным DOM-узлом, который служит обёрткой для передачи списков узлов.
Мы можем добавить к нему другие узлы, но когда мы вставляем его куда-то, он «исчезает», вместо него вставляется его содержимое.
Например, getListContent
ниже генерирует фрагмент с элементами <li>
, которые позже вставляются в <ul>
:
<ul id="ul"></ul>
<script>
function getListContent() {
let fragment = new DocumentFragment();
for(let i=1; i<=3; i++) {
let li = document.createElement('li');
li.append(i);
fragment.append(li);
}
return fragment;
}
ul.append(getListContent()); // (*)
</script>
Обратите внимание, что на последней строке с (*)
мы добавляем DocumentFragment
, но он «исчезает», поэтому структура будет:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
DocumentFragment
редко используется. Зачем добавлять элементы в специальный вид узла, если вместо этого мы можем вернуть массив узлов? Переписанный пример:
<ul id="ul"></ul>
<script>
function getListContent() {
let result = [];
for(let i=1; i<=3; i++) {
let li = document.createElement('li');
li.append(i);
result.push(li);
}
return result;
}
ul.append(...getListContent()); // append + оператор "..." = друзья!
</script>
Мы упоминаем DocumentFragment
в основном потому, что он используется в некоторых других областях, например, для элемента template, который мы рассмотрим гораздо позже.