Aggiunta di una stringa HTML al DOM


121

Come aggiungere questa stringa HTML

var str = '<p>Just some <span>text</span> here</p>';

al DIV con l'ID 'test'che è nel DOM?

(Btw div.innerHTML += str;non è accettabile.)

Risposte:


243

Usa insertAdjacentHTMLse è disponibile, altrimenti usa una sorta di fallback. insertAdjacentHTML è supportato in tutti i browser correnti .

div.insertAdjacentHTML( 'beforeend', str );

Demo dal vivo: http://jsfiddle.net/euQ5n/


1
@alex È lo stesso concetto: analizzare una stringa HTML e inserirla nel DOM. Ma la funzionalità è diversa: innerHTMLinserisce la stringa nell'elemento (sostituendo tutti i figli), mentre la insertAdjacentHTMLmette (1) prima dell'elemento, (2) dopo l'elemento, (3) all'interno dell'elemento prima del primo figlio o (4) all'interno dell'elemento dopo l'ultimo figlio.
Šime Vidas

3
@alex insertAdjacentHTMLè più veloce dell'aggiunta a innerHTML, perché insertAdjacentHTMLnon serializza e analizza gli elementi secondari esistenti dell'elemento.
hsivonen

2
Inoltre, insertAdjacentHTMLmantiene i valori degli elementi del modulo modificati, mentre l'aggiunta a innerHTMLricostruisce l'elemento e perde tutto il contesto del modulo.
Brandon Gano

20

È accettabile?

var child = document.createElement('div');
child.innerHTML = str;
child = child.firstChild;
document.getElementById('test').appendChild(child);

jsFiddle .

Ma , la risposta di Neil è una soluzione migliore.


1
@ Šime Lavorare con l'API DOM sembra sempre un hack: P Preferiresti deserializzare la stringa senza innerHTML ?
alex

Ebbene sì, se c'è un altro modo per utilizzare il parser HTML del browser, mi piacerebbe sapere ...
Šime Vidas

1
@ Šime - Penso che ci siano solo due modi per utilizzare il parser HTML del browser, innerHTML e document.write. E se pensi che innerHTML sia un hack ...
Alohci

@Alohci V'è un altro modo: insertAdjacentHTML.
Šime Vidas

1
@ Šime -Grazie. Ho trovato la versione WHATWG. È nelle specifiche di analisi e serializzazione DOM . Indica che oltre a innerHTML e insertAdjacentHTML, c'è outerHTML e, credo, createContextualFragment.
Alohci

16

Prestazione

AppendChild(E) è più di 2 volte più veloce di altre soluzioni su Chrome e Safari, insertAdjacentHTML(F) è più veloce su Firefox. La innerHTML=(B) (da non confondere con +=(A)) è la seconda soluzione veloce su tutti i browser ed è molto più utile di E ed F.

Dettagli

Configurazione dell'ambiente (2019.07.10) MacOs High Sierra 10.13.4 su Chrome 75.0.3770 (64 bit), Safari 11.1.0 (13604.5.6), Firefox 67.0.0 (64 bit)

inserisci qui la descrizione dell'immagine

  • su Chrome E (140.000 operazioni al secondo) è il più veloce, B (47.000) e F (46.000) sono i secondi, A (332) è il più lento
  • su firefox F (94k) è il più veloce, quindi B (80k), D (73k), E (64k), C (21k) il più lento è A (466)
  • su Safari E (207k) è il più veloce, quindi B (89k), F (88k), D (83k), C (25k), il più lento è A (509)

Puoi riprodurre il test nella tua macchina qui


12

L'idea è di utilizzare innerHTMLun elemento intermedio e quindi spostare tutti i suoi nodi figlio dove li vuoi veramente appendChild.

var target = document.getElementById('test');
var str = '<p>Just some <span>text</span> here</p>';

var temp = document.createElement('div');
temp.innerHTML = str;
while (temp.firstChild) {
  target.appendChild(temp.firstChild);
}

Ciò evita di cancellare tutti i gestori di eventi div#testma consente comunque di aggiungere una stringa di HTML.


3

Il modo giusto è usare insertAdjacentHTML. In Firefox precedente a 8, puoi tornare a utilizzare Range.createContextualFragmentse strnon contiene scripttag.

Se i tag strcontiene script, è necessario rimuovere gli scriptelementi dal frammento restituito da createContextualFragmentprima di inserire il frammento. Altrimenti, gli script verranno eseguiti. ( insertAdjacentHTMLcontrassegna gli script come non eseguibili.)


Grazie per averlo menzionato createContextualFragment . Stavo cercando un modo per eseguire alcuni include html con script solo se l'utente accetta di impostare un cookie.
schliflo

3

Hack rapido :


<script>
document.children[0].innerHTML="<h1>QUICK_HACK</h1>";
</script>

Casi d'uso :

1: salva come file .html ed esegui in chrome, firefox o edge. (IE non funzionerà)

2: utilizzare in http://js.do

In azione: http://js.do/HeavyMetalCookies/quick_hack

Suddiviso con commenti:

<script>

//: The message "QUICK_HACK" 
//: wrapped in a header #1 tag.
var text = "<h1>QUICK_HACK</h1>";

//: It's a quick hack, so I don't
//: care where it goes on the document,
//: just as long as I can see it.
//: Since I am doing this quick hack in
//: an empty file or scratchpad, 
//: it should be visible.
var child = document.children[0];

//: Set the html content of your child
//: to the message you want to see on screen.
child.innerHTML = text;

</script>

Motivo per cui ho pubblicato:

JS.do ha due must have:

  1. Nessun completamento automatico
  2. Compatibile con il monitor verticale

Ma non mostra i messaggi console.log. Sono venuto qui cercando una soluzione rapida. Voglio solo vedere i risultati di poche righe di codice per appunti, le altre soluzioni sono troppo impegnative.


1

Perché non è accettabile?

document.getElementById('test').innerHTML += str

sarebbe il modo da manuale di farlo.


4
Sarebbe uccidere i gestori di eventi collegati a #testperò. Questo generalmente non è desiderabile.
alex

È interessante che lo faccia. Non sembra davvero logico.
Nick Brunt

2
È logico, immagino, se pensi alla serializzazione dell'HTML in una stringa e poi reimpostare l'HTML.
alex

Immagino che JavaScript dovrebbe essere eseguito di nuovo per ripristinare il gestore di eventi. Giusto.
Nick Brunt

1
@ Nick Non vuoi stringere (serializzare) una parte del DOM solo in modo da poterlo concatenare con un'altra stringa e quindi analizzare nuovamente l'intera cosa nel DOM. Come ha detto alex, la serializzazione non registrerà i gestori di eventi associati (tra le altre cose). Anche se la serializzazione potesse catturare tutto, non vorresti comunque farlo.
Šime Vidas

0

Questo può risolvere

 document.getElementById("list-input-email").insertAdjacentHTML('beforeend', '<div class=""><input type="text" name="" value="" class="" /></div>');

3
Benvenuto in Stack overflow. Spiega il tuo codice come parte di una risposta per fornire un contesto piuttosto che incollare semplicemente una lunga singola riga di codice. Anche se lo capisci, altri potrebbero non capire cosa sta facendo.
loan.burger

0

InnerHTML cancella tutti i dati come eventi per i nodi esistenti

aggiungi figlio con firstChild aggiunge solo il primo figlio a innerHTML. Ad esempio, se dobbiamo aggiungere:

 <p>text1</p><p>text2</p>

solo text1 verrà visualizzato

Che dire di questo:

aggiunge un tag speciale a innerHTML accodando il figlio e quindi modifica outerHTML eliminando il tag che abbiamo creato. Non so quanto sia intelligente ma per me funziona o potresti cambiare outerHTML in innerHTML in modo che non debba usare la funzione di sostituzione

function append(element, str)
{

  var child = document.createElement('someshittyuniquetag');
		
  child.innerHTML = str;

  element.appendChild(child);

  child.outerHTML = child.outerHTML.replace(/<\/?someshittyuniquetag>/, '');

// or Even child.outerHTML = child.innerHTML


  
}
<div id="testit">
This text is inside the div
<button onclick="append(document.getElementById('testit'), '<button>dadasasdas</button>')">To div</button>
<button onclick="append(this, 'some text')">to this</button>
</div>


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.