Javascript - Aggiunge HTML all'elemento contenitore senza innerHTML


167

Ho bisogno di un modo per aggiungere HTML a un elemento container senza usare innerHTML. Il motivo per cui non voglio usare innerHTML è perché quando viene usato in questo modo:

element.innerHTML += htmldata

Funziona sostituendo tutto l'html prima di aggiungere il vecchio HTML più il nuovo HTML. Questo non va bene perché ripristina i media dinamici come i video flash incorporati ...

Potrei farlo in questo modo che funziona:

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

Tuttavia, il problema in questo modo è che ora c'è quel tag extra span nel documento che non voglio.

Come si può fare allora? Grazie!


1
Perché non usare Jquery? Controlla la mia risposta dettagliata di seguito. stackoverflow.com/a/50482776/5320562
Loukan ElKadi

Risposte:


102

Per fornire un'alternativa (poiché l'utilizzo DocumentFragmentnon sembra funzionare): puoi simularlo ripetendo i figli del nodo appena generato e aggiungendo solo quelli.

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

while(e.firstChild) {
    element.appendChild(e.firstChild);
}

2
Pensavo che stessimo cercando una soluzione che non usi "innerHTML"
kennydelacruz,

1
@kennydelacruz: l'OP non ha voluto aggiungere nuovo HTML a un HTML esistente perché distrugge e ricrea gli elementi esistenti. L'OP ha trovato una soluzione creando un nuovo elemento e aggiungendolo ma non ha voluto aggiungere un ulteriore elemento. Ho appena esteso quella soluzione per mostrare che possono spostare / aggiungere gli elementi appena creati, che non influiscono sugli elementi esistenti.
Felix Kling,

So che questo è vecchio, ma qualcuno può spiegarmi perché si può iterare su e.firstChild?
Toastgeraet,

1
@Toastgeraet: Questo è esempio non è l'iterazione sopra e.firstChild . Piuttosto, controlla se eha un figlio e se sì, sposta quel figlio sull'elemento.
Felix Kling,

570

Sono sorpreso che nessuna delle risposte abbia menzionato il insertAdjacentHTML()metodo. Dai un'occhiata qui . Il primo parametro è dove si desidera aggiungere la stringa e prendere ("beforebegin", "afterbegin", "beforeend", "afterend"). Nella situazione del PO useresti "prima". Il secondo parametro è solo la stringa html.

Utilizzo di base:

var d1 = document.getElementById('one');
d1.insertAdjacentHTML('beforeend', '<div id="two">two</div>');

53
Ho appena provato la tua soluzione e quella accettata. Entrambi funzionano, ma il tuo è solo 2 righe e nessun loop. Mi sembra un vincitore.
Corwin01,

3
Per riferimento a chiunque possa scegliere questo percorso: questo metodo non funziona bene con i tavoli in IE9.
Corwin01

2
In Chrome mi dice Uncaught TypeError: undefined is not a function!
J86,

19
Questa gemma nascosta ha bisogno di più visibilità.
Seth,

Riceverai un errore se provi a utilizzare questo metodo su qualcosa che non è un nodo, ma solo FYI.
Alex W

15

alnafie ha un'ottima risposta a questa domanda. Volevo fare un esempio del suo codice come riferimento:

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>

Spero che questo sia utile per gli altri.


2
Odio essere un pignolo per le regole, ma penso che sarebbe stato meglio se tu avessi creato una demo (jsfiddle, codepen, ecc.) E poi l'avessi aggiunto alla risposta di Alnafie usando la funzione di modifica o inviando un commento. Creare una risposta solo per dimostrare la risposta di un altro utente non è come funziona SO, indipendentemente da quanto siano utili le informazioni fornite. Immagina se ogni utente decidesse di dimostrare un'altra risposta creando una risposta: diventerebbe confusa.
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>

assegnare i dati per div con il simbolo "+ =" è possibile aggiungere i dati inclusi i precedenti dati HTML


11
La domanda richiede specificamente di non utilizzare element.innerHTML += data.
musicnothing il

1

Questo è DocumentFragmentstato pensato per.

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


Ho appena provato questo e non funziona. È così che dovrebbe essere usato?
Bob,

Da dove vieni (a)? È un errore di battitura.
Ash Burlaczenko,

1
Sì, è un refuso, dovrebbe essere e. Non penso che tu possa usare innerHTML per un frammento. Questo non funziona
Bob,

@Bob Sono andato per l'uso di cop-out jQuery.
Raynos,

jQuery no no! Non includerò jQuery solo per una piccola funzione: \ È solo eccessivo
Bob

-1

Come pescare e usando un codice rigoroso. Ci sono due funzioni preliminari necessarie in fondo a questo post.

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

Aggiungi più elementi (lo spazio dei nomi deve essere solo sull'elemento padre):

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

Codice dinamico riutilizzabile:

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.
 }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.