Когда нужно добавить на страницу новый элемент, безопаснее и понятнее создавать его через DOM-методы, а не собирать HTML строками. Основные инструменты:
document.createElement- создать элементtextContent- задать текстsetAttribute/classList- настроить атрибуты и классыappend/prepend- вставить в DOM
1) createElement: создание элемента
const div = document.createElement("div");
console.log(div.tagName); // "DIV"
Созданный элемент пока не виден на странице. Он появится только после вставки в DOM.
2) Заполнение содержимого
Текст через textContent
const item = document.createElement("li");
item.textContent = "Новый пункт";
Классы и атрибуты
const btn = document.createElement("button");
btn.classList.add("btn", "btn--primary");
btn.setAttribute("type", "button");
btn.setAttribute("data-action", "save");
btn.textContent = "Save";
Несколько атрибутов через свойства
Для некоторых вещей удобно использовать свойства:
const input = document.createElement("input");
input.type = "text";
input.placeholder = "Search";
input.value = "";
3) Вставка: append и prepend
append добавляет элемент в конец контейнера, prepend - в начало.
const list = document.querySelector(".list");
const item = document.createElement("li");
item.textContent = "Item";
list.append(item);
Вставка в начало:
const list = document.querySelector(".list");
const item = document.createElement("li");
item.textContent = "First";
list.prepend(item);
append умеет добавлять несколько узлов сразу:
const box = document.querySelector(".box");
const a = document.createElement("span");
a.textContent = "A";
const b = document.createElement("span");
b.textContent = "B";
box.append(a, b);
4) Вставка относительно элемента: before и after
Иногда нужно вставить рядом, а не внутрь.
const title = document.querySelector("h1");
const badge = document.createElement("span");
badge.textContent = "New";
badge.classList.add("badge");
title.after(badge);
Вставка перед элементом:
const title = document.querySelector("h1");
const note = document.createElement("p");
note.textContent = "Подзаголовок";
title.before(note);
5) Сборка элемента из частей
Частая задача - создать карточку с заголовком и описанием.
const card = document.createElement("div");
card.classList.add("card");
const h2 = document.createElement("h2");
h2.textContent = "Title";
const p = document.createElement("p");
p.textContent = "Description";
card.append(h2, p);
document.body.append(card);
6) Добавление множества элементов: DocumentFragment
Если добавляется много элементов, удобно сначала собрать их во фрагмент, а затем вставить одним действием.
const list = document.querySelector(".list");
const fragment = document.createDocumentFragment();
for (let i = 1; i <= 5; i += 1) {
const item = document.createElement("li");
item.textContent = `Item ${i}`;
fragment.append(item);
}
list.append(fragment);
Так уменьшается количество “перерисовок” страницы.
7) Очистка контейнера
Иногда перед добавлением нового списка нужно очистить старый.
const list = document.querySelector(".list");
list.innerHTML = "";
Если важно избегать innerHTML, можно удалять узлы через цикл:
const list = document.querySelector(".list");
while (list.firstChild) {
list.firstChild.remove();
}
8) Почему создание DOM-узлов часто безопаснее, чем HTML строкой
При создании элементов и использовании textContent текст не превращается в HTML и не исполняется. Это помогает избегать XSS, если данные приходят извне.
const box = document.querySelector(".box");
const value = "<img src=x onerror=\"console.log('XSS')\">";
const p = document.createElement("p");
p.textContent = value;
box.append(p);
В итоге будет показана строка, а не создан <img>.
Частые ошибки
1) Забыть вставить элемент в DOM
const el = document.createElement("div");
el.textContent = "Hello";
Так элемент создан, но на странице его не будет. Нужен append в контейнер.
2) Перепутать append и appendChild
appendChild принимает только один узел и возвращает его. append умеет несколько аргументов и принимает также строки.
const box = document.querySelector(".box");
const a = document.createElement("span");
const b = document.createElement("span");
a.textContent = "A";
b.textContent = "B";
box.append(a, b);
3) Пытаться вставить один и тот же элемент в два места
Один DOM-узел не может быть сразу в двух местах. При повторной вставке он переместится.
const a = document.createElement("div");
a.textContent = "Move";
document.body.append(a);
document.body.append(a);
После второй строки a будет стоять в конце body, а не продублируется.
Что стоит запомнить
createElementсоздает элемент, но он появится на странице только после вставки.- Текст лучше задавать через
textContent. - Вставка в контейнер -
append(конец) иprepend(начало). - Для многих элементов удобны
beforeиafter. - Для больших списков помогает
DocumentFragment. - Создание узлов через DOM часто безопаснее, чем сборка HTML строкой.