Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос нашим менторам. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Манипулирование DOM деревом

То, что DOM-дерево может меняться, уже будучи отрисованным в браузере, и есть ключевая возможность для создания интерактивных приложений.

innerHTML

Самый простой способ обновить часть 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);
// Все специальные символы оказываются замененными
// "&lt;b&gt;make&lt;/b&gt; 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() – удаляет текущий узел.

Старый API

Описанные выше функции появились не так давно. Большая часть кода написана с использованием других функций, список которых ниже:

  • 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 говорит о том, что нужно сделать "глубокую" копию, другими словами, вы получите копию не только этого элемента, но и всех его потомков.


<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят менторы из команды Хекслета или другие студенты.

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, даст возможность обращаться за помощью к менторам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Зарегистрироваться

или войти в аккаунт

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Нажимая кнопку «Зарегистрироваться», вы даёте своё согласие на обработку персональных данных в соответствии с «Политикой конфиденциальности» и соглашаетесь с «Условиями оказания услуг». Защита от спама reCAPTCHA «Конфиденциальность» и «Условия использования».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Нажимая кнопку «Зарегистрироваться», вы даёте своё согласие на обработку персональных данных в соответствии с «Политикой конфиденциальности» и соглашаетесь с «Условиями оказания услуг». Защита от спама reCAPTCHA «Конфиденциальность» и «Условия использования».