Как правильно использовать insertAdjacentHTML ?

Есть некая разметка, где текстовые узлы внутри - без тегов.

<div class="some-class" id="some-id">
text-1
<br>
text-2
<br>
text-3
</div>

Нужно чтобы при клике по кнопке добавились в эту разметку определенные html-теги, например, тег<li>, чтобы в итоге было вот так:
<li>text-1</li> и так для всех одновременно.
Добавить какой-то html-контент можно с помощью insertAdjacentHTML, как-то так:

var xml = function(addtags) {
	var xmlinsert = document.getElementById('some-id').children[0];
	xmlinsert.insertAdjacentHTML(beforeBegin, "<li>");
	console.log(xmlinsert);
} 

в итоге - должны появиться html-теги <li> вначале текста, а чтобы добавить вконце закрывающейся тег - тогда соответственно:
xmlinsert.insertAdjacentHTML(beforeEnd, "</li>");

Но почему-то все это не работает. Возможно причина в неправильной привязке к DOM-узлу (дочернему элементу селектора “some-id”) ?

Код примера полностью по ссылке https://jsfiddle.net/d6oufrq8/1/

В консоли ошибки что beforeBegin не определена. Ожидается аргумент-строка, а записано будто переменная.

Добавил outline для li и поправил ошибку оборачивания:

И документация на MDN для сверки как работать с API Element: insertAdjacentHTML() method - Web APIs | MDN

спасибо за ответ, но немного не тот результат. Ожидается , что с помощью beforeBegin и beforeEnd каждый текстовый узел будет оборачиваться в теги LI. То есть, эта разметка

text-1
<br>
text-2
<br>
text-3

после клика по кнопке должна выглядеть так:

<li> text-1</li>
<br>
<li>text-2</li>
<br>
<li>text-3</li>

Или такого результата добиться - вообще невозможно?

Чтобы обернуть каждый элемент, нужно вызвать insertAdjacentHTML для каждого элемента.

Возможно. Но это сложнее делать, манимулируя элементами из DOM. Намного проще как я советовал в предыдущей теме - имея массив данных в памяти. Тогда генерация желаемой разметки сводится к итерации по массиву.

не понимаю как можно цепляться к данным, когда нет конкретного селектора. Есть общая обертка-div с id=’'some-id". А внутри текст без тегов. Как там можно к этим текстовым узлам getElement… добавить?
вот так будет неправильно? document.getElementById('some-id').children[0];

Сейчас беру пример, где вместо DOM данные находятся в массиве - https://jsfiddle.net/jktr7mox/

HTML

<div id = "id"></div>
<button class = "btn" id = "xml">Show XML</button>

JS

var xml = function(addtags) {
var firstArr = ["text-1", "text-2", "text-3"];
var secondArr = [];
var endxml = secondArr.join('<br>');
    endxml.insertAdjacentHTML('beforeBegin', "<li>");
    endxml.insertAdjacentHTML('beforeEnd', "</li>");
var xmlinsert = document.getElementById('id').innerHTML = endxml;
console.log(xmlinsert);
}
var clickxml = document.getElementById('xml');
clickxml.addEventListener('click', xml, false);

в итоге - ошибка в консоли - endxml.insertAdjacentHTML is not a function
Почему это не функция, если это выражение находится в скобках функции? Или почему такая ошибка?

Выражение написано так будто тип значения в endxml.insertAdjacentHTML - фукция. А там не функция. Это и пытается донести интерпретатор.

Если присмотреться, то в endxml хранится строка: endxml = secondArr.join('<br>'). У строки нет метода insertAdjacentHTML


Когда данные в массиве, то метод оборачивания узла через insertAdjacentHTML не обязательно применять. Можно решить задачу на уровне строк: https://jsfiddle.net/wry0pg2m/

в принципе тоже вариант, но хочется понять именно как insertAdjacentHTML использовать правильно.
Исправила немного код https://jsfiddle.net/bd2jsLf1/

	var xml = function(addtags) {
	var firstArr = ["text-1", "text-2", "text-3"];
  var secondArr = [];
	for (var i = 0; i < firstArr.length; i += 1) {
  secondArr.push(firstArr[i]);
  };		
    var endxml = secondArr.join('<br>');
    endxml.insertAdjacentHTML('beforeBegin', "<li>");
    endxml.insertAdjacentHTML('beforeEnd', "</li>");
	
	document.getElementById('id').innerHTML = endxml;
	console.log(endxml);
};
var clickxml = document.getElementById('xml');
clickxml.addEventListener('click', xml, false);

но все та же ошибка в консоли - endxml.insertAdjacentHTML is not a function

для сравнения, вот такие выражения
document.getElementById('id').innerHTML = endxml;
тоже не функция, но интерпретатор на них не ругается.

То есть - надо это insertAdjacentHTML использовать только как функцию, или что имеется ввиду?

Какой тип данных записан в переменной endxml в твоем коде?

Потому что в этом коде нет попытки вызвать нефункцию, а в коде выше - есть.

тип данных - строка. Ведь html-разметка также относятся к строке, верно?

получается, что в этих строчках кода

endxml.insertAdjacentHTML('beforeBegin', "&lt;li&gt;");

происходит вызов функции , а не присваивание тегов (как передача параметров)?

Метод insertAdjacentHTML есть только у DOM узлов. В строках этого метода нет.

Это вызов, не присваивание. При вызове передаются параметры.

Вот что имею в виду когда говорю о присваивании:

div.innerHTML = '<span>hi</span>'

Вот что имею в виду когда говорю о вызове метода

document.createElement()

А вот что когда говорю что при вызове метода еще и передаются параметры:

body.appendChild(div)
1 лайк

Но по-другому присвоитьinsertAdjacentHTML('beforeBegin', "&amp;lt;li&amp;gt;"); невозможно, у него синтаксис такой что в скобках присваиваются эти параметры - https://developer.mozilla.org/ru/docs/Web/API/Element/insertAdjacentHTML

Я не понимаю о чем ты говоришь. Ты думаешь что можно присвоить значение в insertAdjacentHTML и получить некоторый результат?

ну да, присвоить тег li - перед началом строки (‘beforeBegin’) и второй закрывающий тег li в конце этой строки. То есть если есть строка, обернутая в div (<div>111</div>), то с помощью
endxml.insertAdjacentHTML(‘beforeBegin’, “<li>”);
endxml.insertAdjacentHTML(‘beforeEnd’, “</li>”);
добиться такого результата: <div><li>111</li></div>
Это возможно?

Нет, это невозможно.

insertAdjacentHTML дает возможность вставить разметку как строку. Но не дает возможности работать с DOM узлами как с текстом. В момент вставки разметки она будет интерпретирована как DOM узлы.

И если вставить разметку до узла, то вставленный код будет интерпретирован как неполный HTML. Считай тоже самое что

<div><li>1232</div>

то есть insertAdjacentHTML можно использовать только вместе с document.createElement? А в уже готовую разметку этот метод не может ничего добавить?

В готовую разметку можно добавить код. Нельзя думать что ты работаешь с разметкой как с исходным тектом (типа вставить открывающий тег, вставить закрывающий тег).

1 лайк

то есть можно добавить только строку вместе с тегами? -

d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');

тогда получится такой результат - <div>111</div><div id="two">two</div>
все верно?

Да