Javascript - добавление HTML к элементу контейнера без innerHTML

167

Мне нужен способ добавить HTML к элементу контейнера без использования innerHTML. Причина, по которой я не хочу использовать innerHTML, заключается в том, что когда он используется следующим образом:

element.innerHTML += htmldata

Он работает путем замены всего HTML-кода перед добавлением старого HTML-кода и нового HTML-кода. Это не хорошо, потому что сбрасывает динамические медиа, такие как встроенные флэш-видео ...

Я мог бы сделать это так, который работает:

var e = document.createElement('span');
e.innerHTML = htmldata;
element.appendChild(e);

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

Как это можно сделать тогда? Спасибо!

боб
источник
1
Почему бы не использовать Jquery? Проверьте мой подробный ответ ниже. stackoverflow.com/a/50482776/5320562
Лоукан ЭльКади

Ответы:

102

Чтобы дать альтернативу (поскольку использование DocumentFragment, кажется, не работает): Вы можете смоделировать это, перебирая дочерние элементы недавно сгенерированного узла и добавляя только те

var e = document.createElement('div');
e.innerHTML = htmldata;

while(e.firstChild) {
    element.appendChild(e.firstChild);
}
Феликс Клинг
источник
2
Я думал, что мы ищем решение, которое не использует «innerHTML»
kennydelacruz
1
@kennydelacruz: ОП не хотел добавлять новый HTML в существующий HTML, потому что он уничтожает и воссоздает существующие элементы. ОП нашел решение, создав новый элемент и добавив его, но не хотел добавлять дополнительный элемент. Я просто расширил это решение, чтобы показать, что они могут перемещать / добавлять вновь созданные элементы, которые не влияют на существующие элементы.
Феликс Клинг
Я знаю, что это старо, но кто-нибудь может объяснить мне, почему можно перебирать e.firstChild?
Toastgeraet
1
@Toastgeraet: Это пример не итерация над e.firstChild . Скорее, он проверяет, eесть ли дочерний элемент, и если да, переместите этого дочернего элемента в элемент.
Феликс Клинг
570

Я удивлен, что ни один из ответов не упомянул insertAdjacentHTML()метод. Проверьте это здесь . Первый параметр - это то, где вы хотите, чтобы строка добавлялась и принималась («beforebegin», «afterbegin», «beforeend», «afterend»). В ситуации ОП вы должны использовать «beforeend». Второй параметр - это просто строка html.

Основное использование:

var d1 = document.getElementById('one');
d1.insertAdjacentHTML('beforeend', '<div id="two">two</div>');
alnafie
источник
53
Только что попробовал ваше решение, а также принятое. Оба работают, но у вас только 2 строки и никаких петель. Звучит как победитель для меня.
Corwin01
3
Для справки всем, кто может выбрать этот маршрут: этот метод не очень подходит для таблиц в IE9.
Corwin01
2
В Chrome это говорит мне Uncaught TypeError: undefined is not a function!
J86
19
Этот скрытый драгоценный камень нуждается в большей выдержке.
Сет
Вы получите сообщение об ошибке, если попытаетесь использовать этот метод для чего-то, что не является узлом, а просто для справки.
Алекс Вт
15

У alnafie есть отличный ответ на этот вопрос. Я хотел привести пример его кода для справки:

var childNumber = 3;

function addChild() {
  var parent = document.getElementById('i-want-more-children');
  var newChild = '<p>Child ' + childNumber + '</p>';
  parent.insertAdjacentHTML('beforeend', newChild);
  childNumber++;
}
body {
  text-align: center;
}
button {
  background: rgba(7, 99, 53, .1);
  border: 3px solid rgba(7, 99, 53, 1);
  border-radius: 5px;
  color: rgba(7, 99, 53, 1);
  cursor: pointer;
  line-height: 40px;
  font-size: 30px;
  outline: none;
  padding: 0 20px;
  transition: all .3s;
}
button:hover {
  background: rgba(7, 99, 53, 1);
  color: rgba(255,255,255,1);
}
p {
  font-size: 20px;
  font-weight: bold;
}
<button type="button" onclick="addChild()">Append Child</button>
<div id="i-want-more-children">
  <p>Child 1</p>
  <p>Child 2</p>
</div>

Надеюсь, это полезно для других.

Тревор Нестман
источник
2
Я не хочу быть сторонником правил, но я думаю, что было бы лучше, если бы вы создали демо (jsfiddle, codepen и т. Д.), А затем добавили его в ответ Алнафи, используя функцию редактирования или отправив комментарий. Создание ответа только для демонстрации ответа другого пользователя - это не то, как работает SO, независимо от того, насколько полезна предоставленная вами информация. Представьте себе, что если бы каждый пользователь решил продемонстрировать другой ответ, создав ответ, это было бы грязно.
Мартин Джеймс
2
<div id="Result">
</div>

<script>
for(var i=0; i<=10; i++){
var data = "<b>vijay</b>";
 document.getElementById('Result').innerHTML += data;
}
</script>

назначьте данные для div с символом «+ =», к которому вы можете добавить данные, включая предыдущие HTML-данные

Виджей
источник
11
Вопрос конкретно не требует использования element.innerHTML += data.
musicnothing
1

Это то, что DocumentFragmentпредназначалось для.

var frag = document.createDocumentFragment();
var span = document.createElement("span");
span.innerHTML = htmldata;
for (var i = 0, ii = span.childNodes.length; i < ii; i++) {
    frag.appendChild(span.childNodes[i]);
}
element.appendChild(frag);

document.createDocumentFragment, .childNodes

Raynos
источник
Я только что проверил это, и это не работает. Так ли это?
Боб
Откуда ты (a)? Это опечатка.
Эш Бурлаченко
1
Да, это опечатка, это должно быть е. Я не думаю, что вы можете использовать innerHTML для фрагмента. Это не работает
Боб
@Bob Я пошел на отговорку использовать JQuery.
Райнос
jQuery нет нет! Я не собираюсь включать jQuery только для одной маленькой функции: \ Это просто излишество
Боб
-1

Как ловить рыбу и при этом использовать строгий кодекс. В нижней части этого поста необходимы две обязательные функции.

xml_add('before', id_('element_after'), '<span xmlns="http://www.w3.org/1999/xhtml">Some text.</span>');

xml_add('after', id_('element_before'), '<input type="text" xmlns="http://www.w3.org/1999/xhtml" />');

xml_add('inside', id_('element_parent'), '<input type="text" xmlns="http://www.w3.org/1999/xhtml" />');

Добавьте несколько элементов (пространство имен должно быть только в родительском элементе):

xml_add('inside', id_('element_parent'), '<div xmlns="http://www.w3.org/1999/xhtml"><input type="text" /><input type="button" /></div>');

Динамический многоразовый код:

function id_(id) {return (document.getElementById(id)) ? document.getElementById(id) : false;}

function xml_add(pos, e, xml)
{
 e = (typeof e == 'string' && id_(e)) ? id_(e) : e;

 if (e.nodeName)
 {
  if (pos=='after') {e.parentNode.insertBefore(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true),e.nextSibling);}
  else if (pos=='before') {e.parentNode.insertBefore(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true),e);}
  else if (pos=='inside') {e.appendChild(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true));}
  else if (pos=='replace') {e.parentNode.replaceChild(document.importNode(new DOMParser().parseFromString(xml,'application/xml').childNodes[0],true),e);}
  //Add fragment and have it returned.
 }
}
Джон
источник