Element.append()
Метод Element.append() вставляет узлы или строки с текстом в конец Element . Строки с текстом вставляются как текстовое содержимое .
- Метод Element.append() позволяет вставлять строки с текстом , в то время как Node.appendChild() работает только с узлами .
- При вызове метод Element.append() ничего не возвращает, в то время как Node.appendChild() возвращает вставленный узел .
- С помощью Element.append() можно вставить сразу несколько узлов или строк текста, в то время как Node.appendChild() умеет вставлять по одной сущности за раз.
Синтаксис
Аргументы
Один или несколько узлов или строк с текстом , которые необходимо вставить.
Исключения
Случается, когда узел не может быть вставлен в существующую иерархию элементов.
Изменение документа
Модификации DOM – это ключ к созданию «живых» страниц.
Здесь мы увидим, как создавать новые элементы «на лету» и изменять уже существующие.
Пример: показать сообщение
Рассмотрим методы на примере – а именно, добавим на страницу сообщение, которое будет выглядеть получше, чем alert .
Это был пример HTML. Теперь давайте создадим такой же div , используя JavaScript (предполагаем, что стили в HTML или во внешнем CSS-файле).
Создание элемента
DOM-узел можно создать двумя методами:
Создаёт новый элемент с заданным тегом:
Создаёт новый текстовый узел с заданным текстом:
Большую часть времени нам нужно создавать узлы элементов, такие как div для сообщения.
Создание сообщения
В нашем случае сообщение – это div с классом alert и HTML в нём:
Мы создали элемент, но пока он только в переменной. Мы не можем видеть его на странице, поскольку он не является частью документа.
Методы вставки
Чтобы наш div появился, нам нужно вставить его где-нибудь в document . Например, в document.body .
Для этого есть метод append , в нашем случае: document.body.append(div) .
Вот полный пример:
Вот методы для различных вариантов вставки:
- node.append(. nodes or strings) – добавляет узлы или строки в конец node ,
- node.prepend(. nodes or strings) – вставляет узлы или строки в начало node ,
- node.before(. nodes or strings) –- вставляет узлы или строки до node ,
- node.after(. nodes or strings) –- вставляет узлы или строки после node ,
- node.replaceWith(. nodes or strings) –- заменяет node заданными узлами или строками.
Вот пример использования этих методов, чтобы добавить новые элементы в список и текст до/после него:
Наглядная иллюстрация того, куда эти методы вставляют:
Итоговый список будет таким:
Эти методы могут вставлять несколько узлов и текстовых фрагментов за один вызов.
Например, здесь вставляется строка и элемент:
Весь текст вставляется как текст.
Поэтому финальный HTML будет:
Другими словами, строки вставляются безопасным способом, как делает это elem.textContent .
Поэтому эти методы могут использоваться только для вставки DOM-узлов или текстовых фрагментов.
А что, если мы хотим вставить HTML именно «как html», со всеми тегами и прочим, как делает это elem.innerHTML ?
insertAdjacentHTML/Text/Element
С этим может помочь другой, довольно универсальный метод: elem.insertAdjacentHTML(where, html) .
Первый параметр – это специальное слово, указывающее, куда по отношению к elem производить вставку. Значение должно быть одним из следующих:
- "beforebegin" – вставить html непосредственно перед elem ,
- "afterbegin" – вставить html в начало elem ,
- "beforeend" – вставить html в конец elem ,
- "afterend" – вставить html непосредственно после elem .
Второй параметр – это HTML-строка, которая будет вставлена именно «как HTML».
Так мы можем добавлять произвольный HTML на страницу.
Мы можем легко заметить сходство между этой и предыдущей картинкой. Точки вставки фактически одинаковые, но этот метод вставляет HTML.
У метода есть два брата:
- elem.insertAdjacentText(where, text) – такой же синтаксис, но строка text вставляется «как текст», вместо HTML,
- elem.insertAdjacentElement(where, elem) – такой же синтаксис, но вставляет элемент elem .
Они существуют, в основном, чтобы унифицировать синтаксис. На практике часто используется только insertAdjacentHTML . Потому что для элементов и текста у нас есть методы append/prepend/before/after – их быстрее написать, и они могут вставлять как узлы, так и текст.
Так что, вот альтернативный вариант показа сообщения:
Удаление узлов
Для удаления узла есть методы node.remove() .
Например, сделаем так, чтобы наше сообщение удалялось через секунду:
Если нам нужно переместить элемент в другое место – нет необходимости удалять его со старого.
Все методы вставки автоматически удаляют узлы со старых мест.
Например, давайте поменяем местами элементы:
Клонирование узлов: cloneNode
Как вставить ещё одно подобное сообщение?
Мы могли бы создать функцию и поместить код туда. Альтернатива – клонировать существующий div и изменить текст внутри него (при необходимости).
Иногда, когда у нас есть большой элемент, это может быть быстрее и проще.
- Вызов elem.cloneNode(true) создаёт «глубокий» клон элемента – со всеми атрибутами и дочерними элементами. Если мы вызовем elem.cloneNode(false) , тогда клон будет без дочерних элементов.
Пример копирования сообщения:
DocumentFragment
DocumentFragment является специальным DOM-узлом, который служит обёрткой для передачи списков узлов.
Мы можем добавить к нему другие узлы, но когда мы вставляем его куда-то, он «исчезает», вместо него вставляется его содержимое.
Например, getListContent ниже генерирует фрагмент с элементами <li> , которые позже вставляются в <ul> :
Обратите внимание, что на последней строке с (*) мы добавляем DocumentFragment , но он «исчезает», поэтому структура будет:
DocumentFragment редко используется. Зачем добавлять элементы в специальный вид узла, если вместо этого мы можем вернуть массив узлов? Переписанный пример:
Мы упоминаем DocumentFragment в основном потому, что он используется в некоторых других областях, например, для элемента template, который мы рассмотрим гораздо позже.
Устаревшие методы вставки/удаления
Есть несколько других, более старых, методов вставки и удаления, которые существуют по историческим причинам.
Сейчас уже нет причин их использовать, так как современные методы append , prepend , before , after , remove , replaceWith более гибкие и удобные.
Мы упоминаем о них только потому, что их можно найти во многих старых скриптах:
Добавляет node в конец дочерних элементов parentElem .
Следующий пример добавляет новый <li> в конец <ol> :
Вставляет node перед nextSibling в parentElem .
Следующий пример вставляет новый элемент перед вторым <li> :
Чтобы вставить newLi в начало, мы можем сделать вот так:
Заменяет oldChild на node среди дочерних элементов parentElem .
Удаляет node из parentElem (предполагается, что он родитель node ).
Этот пример удалит первый <li> из <ol> :
Все эти методы возвращают вставленный/удалённый узел. Другими словами, parentElem.appendChild(node) вернёт node . Но обычно возвращаемое значение не используют, просто вызывают метод.
Несколько слов о «document.write»
Есть ещё один, очень древний метод добавления содержимого на веб-страницу: document.write .
Вызов document.write(html) записывает html на страницу «прямо здесь и сейчас». Строка html может быть динамически сгенерирована, поэтому метод достаточно гибкий. Мы можем использовать JavaScript, чтобы создать полноценную веб-страницу и записать её в документ.
Этот метод пришёл к нам со времён, когда ещё не было ни DOM, ни стандартов… Действительно старые времена. Он всё ещё живёт, потому что есть скрипты, которые используют его.
В современных скриптах он редко встречается из-за следующего важного ограничения:
Вызов document.write работает только во время загрузки страницы.
Если вызвать его позже, то существующее содержимое документа затрётся.
Так что после того, как страница загружена, он уже непригоден к использованию, в отличие от других методов DOM, которые мы рассмотрели выше.
Это его недостаток.
Есть и преимущество. Технически, когда document.write запускается во время чтения HTML браузером, и что-то пишет в документ, то браузер воспринимает это так, как будто это изначально было частью загруженного HTML-документа.
Поэтому он работает невероятно быстро, ведь при этом нет модификации DOM. Метод пишет прямо в текст страницы, пока DOM ещё в процессе создания.
Так что, если нам нужно динамически добавить много текста в HTML, и мы находимся на стадии загрузки, и для нас очень важна скорость, это может помочь. Но на практике эти требования редко сочетаются. И обычно мы можем увидеть этот метод в скриптах просто потому, что они старые.
Итого
Методы для создания узлов:
- document.createElement(tag) – создаёт элемент с заданным тегом,
- document.createTextNode(value) – создаёт текстовый узел (редко используется),
- elem.cloneNode(deep) – клонирует элемент, если deep==true , то со всеми дочерними элементами.
Вставка и удаление:
- node.append(. nodes or strings) – вставляет в node в конец,
- node.prepend(. nodes or strings) – вставляет в node в начало,
- node.before(. nodes or strings) – вставляет прямо перед node ,
- node.after(. nodes or strings) – вставляет сразу после node ,
- node.replaceWith(. nodes or strings) – заменяет node .
- node.remove() – удаляет node .
- parent.appendChild(node)
- parent.insertBefore(node, nextSibling)
- parent.removeChild(node)
- parent.replaceChild(newElem, node)
Все эти методы возвращают node .
Если нужно вставить фрагмент HTML, то elem.insertAdjacentHTML(where, html) вставляет в зависимости от where :
- "beforebegin" – вставляет html прямо перед elem ,
- "afterbegin" – вставляет html в elem в начало,
- "beforeend" – вставляет html в elem в конец,
- "afterend" – вставляет html сразу после elem .
Также существуют похожие методы elem.insertAdjacentText и elem.insertAdjacentElement , они вставляют текстовые строки и элементы, но они редко используются.
Чтобы добавить HTML на страницу до завершения её загрузки:
- document.write(html)
После загрузки страницы такой вызов затирает документ. В основном встречается в старых скриптах.
Как в JavaScript вставить текст в HTML элемент?
.append() мне помогло чтобы дописать к существующему тексту, не удаляя тот который есть, по скольку innetHTML переписывает.
пример:
const link = document.querySelector(‘a’);
link.append(‘ my link’)

А то, что вылезает за пределы — фиксится средствами CSS, самое банальное overflow: hidden
Modifying the document
DOM modification is the key to creating “live” pages.
Here we’ll see how to create new elements “on the fly” and modify the existing page content.
Example: show a message
Let’s demonstrate using an example. We’ll add a message on the page that looks nicer than alert .
Here’s how it will look:
That was the HTML example. Now let’s create the same div with JavaScript (assuming that the styles are in the HTML/CSS already).
Creating an element
To create DOM nodes, there are two methods:
Creates a new element node with the given tag:
Creates a new text node with the given text:
Most of the time we need to create element nodes, such as the div for the message.
Creating the message
Creating the message div takes 3 steps:
We’ve created the element. But as of now it’s only in a variable named div , not in the page yet. So we can’t see it.
Insertion methods
To make the div show up, we need to insert it somewhere into document . For instance, into <body> element, referenced by document.body .
There’s a special method append for that: document.body.append(div) .
Here’s the full code:
Here we called append on document.body , but we can call append method on any other element, to put another element into it. For instance, we can append something to <div> by calling div.append(anotherElement) .
Here are more insertion methods, they specify different places where to insert:
- node.append(. nodes or strings) – append nodes or strings at the end of node ,
- node.prepend(. nodes or strings) – insert nodes or strings at the beginning of node ,
- node.before(. nodes or strings) –- insert nodes or strings before node ,
- node.after(. nodes or strings) –- insert nodes or strings after node ,
- node.replaceWith(. nodes or strings) –- replaces node with the given nodes or strings.
Arguments of these methods are an arbitrary list of DOM nodes to insert, or text strings (that become text nodes automatically).
Let’s see them in action.
Here’s an example of using these methods to add items to a list and the text before/after it:
Here’s a visual picture of what the methods do:
So the final list will be:
As said, these methods can insert multiple nodes and text pieces in a single call.
For instance, here a string and an element are inserted:
Please note: the text is inserted “as text”, not “as HTML”, with proper escaping of characters such as < , > .
So the final HTML is:
In other words, strings are inserted in a safe way, like elem.textContent does it.
So, these methods can only be used to insert DOM nodes or text pieces.
But what if we’d like to insert an HTML string “as html”, with all tags and stuff working, in the same manner as elem.innerHTML does it?
insertAdjacentHTML/Text/Element
For that we can use another, pretty versatile method: elem.insertAdjacentHTML(where, html) .
The first parameter is a code word, specifying where to insert relative to elem . Must be one of the following:
- "beforebegin" – insert html immediately before elem ,
- "afterbegin" – insert html into elem , at the beginning,
- "beforeend" – insert html into elem , at the end,
- "afterend" – insert html immediately after elem .
The second parameter is an HTML string, that is inserted “as HTML”.
That’s how we can append arbitrary HTML to the page.
Here’s the picture of insertion variants:
We can easily notice similarities between this and the previous picture. The insertion points are actually the same, but this method inserts HTML.
The method has two brothers:
- elem.insertAdjacentText(where, text) – the same syntax, but a string of text is inserted “as text” instead of HTML,
- elem.insertAdjacentElement(where, elem) – the same syntax, but inserts an element.
They exist mainly to make the syntax “uniform”. In practice, only insertAdjacentHTML is used most of the time. Because for elements and text, we have methods append/prepend/before/after – they are shorter to write and can insert nodes/text pieces.
So here’s an alternative variant of showing a message:
Node removal
To remove a node, there’s a method node.remove() .
Let’s make our message disappear after a second:
Please note: if we want to move an element to another place – there’s no need to remove it from the old one.
All insertion methods automatically remove the node from the old place.
For instance, let’s swap elements:
Cloning nodes: cloneNode
How to insert one more similar message?
We could make a function and put the code there. But the alternative way would be to clone the existing div and modify the text inside it (if needed).
Sometimes when we have a big element, that may be faster and simpler.
- The call elem.cloneNode(true) creates a “deep” clone of the element – with all attributes and subelements. If we call elem.cloneNode(false) , then the clone is made without child elements.
An example of copying the message:
DocumentFragment
DocumentFragment is a special DOM node that serves as a wrapper to pass around lists of nodes.
We can append other nodes to it, but when we insert it somewhere, then its content is inserted instead.
For example, getListContent below generates a fragment with <li> items, that are later inserted into <ul> :
Please note, at the last line (*) we append DocumentFragment , but it “blends in”, so the resulting structure will be:
DocumentFragment is rarely used explicitly. Why append to a special kind of node, if we can return an array of nodes instead? Rewritten example:
We mention DocumentFragment mainly because there are some concepts on top of it, like template element, that we’ll cover much later.
Old-school insert/remove methods
There are also “old school” DOM manipulation methods, existing for historical reasons.
These methods come from really ancient times. Nowadays, there’s no reason to use them, as modern methods, such as append , prepend , before , after , remove , replaceWith , are more flexible.
The only reason we list these methods here is that you can find them in many old scripts:
Appends node as the last child of parentElem .
The following example adds a new <li> to the end of <ol> :
Inserts node before nextSibling into parentElem .
The following code inserts a new list item before the second <li> :
To insert newLi as the first element, we can do it like this:
Replaces oldChild with node among children of parentElem .
Removes node from parentElem (assuming node is its child).
The following example removes first <li> from <ol> :
All these methods return the inserted/removed node. In other words, parentElem.appendChild(node) returns node . But usually the returned value is not used, we just run the method.
A word about “document.write”
There’s one more, very ancient method of adding something to a web-page: document.write .
The call to document.write(html) writes the html into page “right here and now”. The html string can be dynamically generated, so it’s kind of flexible. We can use JavaScript to create a full-fledged webpage and write it.
The method comes from times when there was no DOM, no standards… Really old times. It still lives, because there are scripts using it.
In modern scripts we can rarely see it, because of the following important limitation:
The call to document.write only works while the page is loading.
If we call it afterwards, the existing document content is erased.
So it’s kind of unusable at “after loaded” stage, unlike other DOM methods we covered above.
That’s the downside.
There’s an upside also. Technically, when document.write is called while the browser is reading (“parsing”) incoming HTML, and it writes something, the browser consumes it just as if it were initially there, in the HTML text.
So it works blazingly fast, because there’s no DOM modification involved. It writes directly into the page text, while the DOM is not yet built.
So if we need to add a lot of text into HTML dynamically, and we’re at page loading phase, and the speed matters, it may help. But in practice these requirements rarely come together. And usually we can see this method in scripts just because they are old.
Summary
Methods to create new nodes:
- document.createElement(tag) – creates an element with the given tag,
- document.createTextNode(value) – creates a text node (rarely used),
- elem.cloneNode(deep) – clones the element, if deep==true then with all descendants.
Insertion and removal:
- node.append(. nodes or strings) – insert into node , at the end,
- node.prepend(. nodes or strings) – insert into node , at the beginning,
- node.before(. nodes or strings) –- insert right before node ,
- node.after(. nodes or strings) –- insert right after node ,
- node.replaceWith(. nodes or strings) –- replace node .
- node.remove() –- remove the node .
Text strings are inserted “as text”.
There are also “old school” methods:
- parent.appendChild(node)
- parent.insertBefore(node, nextSibling)
- parent.removeChild(node)
- parent.replaceChild(newElem, node)
All these methods return node .
Given some HTML in html , elem.insertAdjacentHTML(where, html) inserts it depending on the value of where :
- "beforebegin" – insert html right before elem ,
- "afterbegin" – insert html into elem , at the beginning,
- "beforeend" – insert html into elem , at the end,
- "afterend" – insert html right after elem .
Also there are similar methods, elem.insertAdjacentText and elem.insertAdjacentElement , that insert text strings and elements, but they are rarely used.
To append HTML to the page before it has finished loading:
- document.write(html)
After the page is loaded such a call erases the document. Mostly seen in old scripts.