Подтвердить что ты не робот

Как правильно использовать 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>]
4b9b3361

Ответ 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> - элемент уровня блока).