Как правильно использовать innerHTML для создания элемента (с возможными дочерними элементами) из строки html?
Примечание. Я использую НЕ любую фреймворк.
Цель состоит в том, чтобы создать функцию, которая вернет элемент на основе строки HTML.
Возьмем простой HTML-документ, например:
<html>
<head></head>
<body>
</body>
</html>
Все упомянутые функции включены в раздел главы, и все создание/манипулирование DOM выполняется в конце тела в теге script.
У меня есть функция createElement, которая принимает хорошо сформированную строку HTML в качестве аргумента. Это происходит следующим образом:
function createElement(str)
{
var div = document.createElement('div');
div.innerHTML = str;
return div.childNodes;
}
Теперь эти функции отлично работают, когда вы вызываете их так:
var e = createElement('<p id="myId" class="myClass">myInnerHTML</p>');
С незначительной (возможно, ОГРОМНОЙ) проблемой, что созданный элемент не является "истинным" элементом, он все еще имеет parentNode "div". Если кто-нибудь знает, как это исправить, тогда это будет потрясающе.
Теперь, если я вызываю одну и ту же функцию с более сложной строкой:
var e = createElement('<p id="myId" class="myClass">innerHTML<h2 id="h2ID" class="h2CLASS">Heading2</h2></p>');
Он создает ДВОЕ детей вместо ОДНОГО ребенка, а другой ребенок имеет другого ребенка.
После того, как вы сделаете div.innerHTML = str. innerHTML вместо
`<p id="myId" class="myClass">innerHTML <h2 id="h2ID" class="h2CLASS">Heading2</h2> </p>`
превращается в
`<p id="myId" class="myClass">innerHTML</p> <h2 id="h2ID" class="h2CLASS">Heading2</h2>`
Вопросы:
- Можно ли каким-то образом получить элемент без родительского node после использования .innerHTML?
- Могу ли я (в случае немного сложной строки) получить мою функцию, чтобы вернуть один элемент с соответствующим дочерним элементом вместо двух элементов. [Он фактически возвращает три,
<p.myClass#myId>
, <h2.h2CLASS#h2ID>
и еще один <p>
]
Ответы
Ответ 1
Это похоже на ответ от palswim
, за исключением того, что он не беспокоится о создании клона и вместо этого использует цикл while()
, всегда добавляя node в [0]
.
function createElement( str ) {
var frag = document.createDocumentFragment();
var elem = document.createElement('div');
elem.innerHTML = str;
while (elem.childNodes[0]) {
frag.appendChild(elem.childNodes[0]);
}
return frag;
}
Ответ 2
Вам нужно будет прикрепить новый элемент. Попробуйте использовать объект DocumentFragment
в сочетании с созданным div
:
function createElement(str) {
var div = document.createElement('div');
div.innerHTML = str;
var container = document.createDocumentFragment();
for (var i=0; i < div.childNodes.length; i++) {
var node = div.childNodes[i].cloneNode(true);
container.appendChild(node);
}
return container.childNodes;
}
Это больше накладных расходов, но он делает то, что вы хотите. Обратите внимание, что функция элемента .insertAdjacentHTML
элементов DOM входит в HTML5.
Для этой сложной строки, которую вы передали, это недопустимый синтаксис XHTML - вы не можете иметь элемент блока в качестве дочернего элемента <p>
(<h2>
- элемент уровня блока).