То, что DOM-дерево может меняться, уже будучи отрисованным в браузере, и есть ключевая возможность для создания интерактивных приложений.
Самый простой способ обновить часть DOM — это свойство innerHTML
:
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>
const body = document.body;
console.log(body);
// <ul><li>item 1</li><li>item 2</li></ul>
body.innerHTML = '<b>make</b> love';
console.log(body.innerHTML);
// <b>make</b> love
console.log(body.childNodes);
// [b, text]
Значение этого свойства целиком заменяет потомков элемента, на котором оно было вызвано. Весь встречающийся внутри HTML анализируется и становится частью дерева. Если вы пытаетесь вставить обычный текст, который потенциально может содержать HTML (Это позволяет проводить XSS атаки), то лучше воспользоваться другим свойством – textContent
.
textContent
работает практически идентично, оно также заменяет всех потомков. Главное отличие между этими свойствами заключается в том, что textContent
рассматривает свое содержимое как обычный текст в любом случае, даже если там есть HTML.
document.body.textContent = '<b>make</b> love';
console.log(document.body.innerHTML);
// Все специальные символы оказываются замененными
// "<b>make</b> love"
innerHTML
работает со строками, такой подход удобен только в том случае, когда мы работаем со статическим представлением DOM. Для динамического формирования хорошо подходят специальные функции.
// Создаем текстовый узел
const textNode = document.createTextNode('life is life');
// Создаем элемент p
const pEl = document.createElement('p');
// Добавляем textNode в конец списка childNodes элемента pEl
pEl.append(textNode);
// pEl.textContent = 'life is life';
const el = document.createElement('div');
el.append(pEl);
console.log(el);
// <div><p>life is life</p></div>
Код, создающий DOM динамически, похож на матрешку. После создания одни элементы все время вкладываются в другие. Так выглядит код, который конструирует деревья в любом языке.
ParentNode.prepend() добавляет переданный узел (или узлы) первым ребенком в ParentNode
:
const div = document.createElement('div');
div.innerHTML = '<span>Hexlet</span>';
const el = document.createElement('p');
el.textContent = 'prepend';
div.prepend(el);
// <div>
// <p>prepend</p>
// <span>Hexlet</span>
// </div>
ParentNode.append() добавляет переданный узел (или узлы) последним ребенком в ParentNode
:
const div = document.createElement('div');
div.innerHTML = '<span>Hexlet</span>';
const el = document.createElement('p');
el.textContent = 'append';
div.append(el);
// <div>
// <span>Hexlet</span>
// <p>append</p>
// </div>
childNode.before(...nodes) – вставляет nodes
в список детей родительского узла childNode
прямо перед childNode
.
const div = document.createElement('div');
div.innerHTML = '<span>Hexlet</span>';
// Должен быть вставлен в DOM-дерево
document.body.append(div);
const el = document.createElement('p');
el.textContent = 'content';
div.before(el);
// <p>content</p>
// <div>
// <span>Hexlet</span>
// </div>
childNode.after(...nodes) – вставляет nodes
в список детей родительского узла childNode
сразу после childNode
.
const div = document.createElement('div');
div.innerHTML = '<span>Hexlet</span>';
// Должен быть вставлен в DOM-дерево
document.body.append(div);
const el = document.createElement('p');
el.textContent = 'content';
div.after(el);
// <div>
// <span>Hexlet</span>
// </div>
// <p>content</p>
node.replaceWith(...nodes) – вставляет nodes вместо node
. Сама node
пропадает из DOM-дерева, но остается доступной в коде.
const div = document.createElement('div');
div.innerHTML = '<span>Hexlet</span>';
// Должен быть вставлен в DOM-дерево
document.body.append(div);
const el = document.createElement('p');
el.textContent = 'content';
div.replaceWith(el);
// В Dom-дереве вместо div остался p
// <p>content</p>
node.remove()
– удаляет текущий узел.
Описанные выше функции появились не так давно. Большая часть кода написана с использованием других функций, список которых ниже:
parent.appendChild(el)
– добавляет el
в конец списка детейparent.insertBefore(el, nextElSibling)
– добавляет el
в
список детей parent
перед nextElSibling
parent.removeChild(el)
– удаляет el
из детей parent
parent.replaceChild(newEl, el)
– заменяет el
на newEl
Иногда требуется создать элемент, подобный уже существующему. Можно, конечно, это сделать полностью руками, копируя свойства одного в свойства другого, но есть способ проще:
const newEl = el.cloneNode(true);
true
говорит о том, что нужно сделать "глубокую" копию, другими словами, вы получите копию не только этого элемента, но и всех его потомков.
Вам ответят команда поддержки Хекслета или другие студенты.
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Загляните в раздел «Обсуждение»:
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.
Зарегистрируйтесь или войдите в свой аккаунт