Javascript - Anexar HTML ao elemento de contêiner sem innerHTML

167

Eu preciso de uma maneira de acrescentar HTML a um elemento de contêiner sem usar innerHTML. A razão pela qual eu não quero usar innerHTML é porque quando é usado assim:

element.innerHTML += htmldata

Ele funciona substituindo todo o html primeiro antes de adicionar o html antigo mais o novo html. Isso não é bom porque redefine a mídia dinâmica, como vídeos em flash incorporados ...

Eu poderia fazê-lo desta maneira, que funciona:

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

No entanto, o problema dessa maneira é que existe uma tag de extensão extra no documento agora que eu não quero.

Como isso pode ser feito então? Obrigado!

Prumo
fonte
1
Por que não usar Jquery? Verifique minha resposta detalhada abaixo. stackoverflow.com/a/50482776/5320562
Loukan ElKadi /

Respostas:

102

Para fornecer uma alternativa (como o uso DocumentFragmentnão parece funcionar): Você pode simulá-lo iterando sobre os filhos do nó recém-gerado e anexá-los apenas.

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

while(e.firstChild) {
    element.appendChild(e.firstChild);
}
Felix Kling
fonte
2
Eu pensei que nós estamos procurando uma solução que não usa "innerHTML"
kennydelacruz
1
@kennydelacruz: o OP não quis acrescentar novo HTML a um HTML existente porque destrói e recria os elementos existentes. O OP encontrou uma solução criando um novo elemento e anexou-o, mas não queria adicionar um elemento adicional. Acabei de estender essa solução para mostrar que eles podem mover / acrescentar os elementos recém-criados, que não afetam os elementos existentes.
Felix Kling
Eu sei que isso é antigo, mas alguém pode me explicar por que alguém pode interagir com o e.firstChild?
Toastgeraet
1
@Toastgeraet: Este é um exemplo não está interagindo mais e.firstChild . Em vez disso, verifica se etem um filho e, se sim, mova esse filho para o elemento
Felix Kling
570

Estou surpreso que nenhuma das respostas mencionou o insertAdjacentHTML()método. Confira aqui . O primeiro parâmetro é onde você deseja que a string seja anexada e leva ("beforebegin", "afterbegin", "beforeend", "afterend"). Na situação do OP, você usaria "beforeend". O segundo parâmetro é apenas a string html.

Uso básico:

var d1 = document.getElementById('one');
d1.insertAdjacentHTML('beforeend', '<div id="two">two</div>');
alnafie
fonte
53
Apenas tentei sua solução e também a aceita. Ambos funcionam, mas o seu é de apenas 2 linhas e sem loops. Parece um vencedor para mim.
Corwin01
3
Para referência a qualquer pessoa que possa escolher esta rota: Este método não funciona bem com tabelas no IE9.
Corwin01
2
No Chrome, isso me diz Uncaught TypeError: undefined is not a function!
J86
19
Esta jóia escondida precisa de mais exposição.
Seth
Você receberá um erro se tentar usar esse método em algo que não é um Nó, apenas para sua informação.
Alex W
15

alnafie tem uma ótima resposta para esta pergunta. Eu queria dar um exemplo de seu código para referência:

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>

Espero que isso seja útil para os outros.

Trevor Nestman
fonte
2
Eu odeio ser um defensor das regras, mas acho que seria melhor se você criasse uma demonstração (jsfiddle, codepen, etc) e a adicionasse à resposta de Alnafie usando o recurso de edição ou enviando um comentário. Criar uma resposta apenas para demonstrar a resposta de outro usuário não é como o SO funciona, independentemente da utilidade das informações fornecidas. Imagine se todo usuário decidisse demonstrar outra resposta criando uma resposta - isso seria confuso.
Martin James
2
<div id="Result">
</div>

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

atribuir os dados para div com o símbolo "+ =", você pode anexar dados, incluindo dados html anteriores

vijay
fonte
11
A pergunta requer especificamente não usar element.innerHTML += data.
musicnothing
1

É para isso que DocumentFragmentse destina.

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
fonte
Acabei de testar isso e não funciona. É assim que deve ser usado?
Bob
De onde você está indo (a)? Isso é um erro de digitação?
Ash Burlaczenko
1
Sim, isso é um erro de digitação, deve ser e. Eu não acho que você pode usar innerHTML para um fragmento. Isto não está funcionando
Bob
@ Bob Fui para o cop-out usar jQuery.
Raynos
jQuery não, não! Eu não estou indo para incluir jQuery apenas por uma função pequeno: \ Ele é apenas um exagero
Bob
-1

Como pescar e usar código estrito. Existem duas funções de pré-requisito necessárias na parte inferior desta postagem.

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" />');

Adicione vários elementos (o espaço para nome precisa apenas estar no elemento pai):

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

Código reutilizável dinâmico:

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.
 }
}
John
fonte