Anhängen einer HTML-Zeichenfolge an das DOM

121

So hängen Sie diese HTML-Zeichenfolge an

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

zum DIV mit der ID, 'test'die sich im DOM befindet?

(Übrigens div.innerHTML += str;ist nicht akzeptabel.)

Šime Vidas
quelle

Antworten:

241

Verwenden Sie, insertAdjacentHTMLwenn es verfügbar ist, andernfalls verwenden Sie eine Art Fallback. insertAdjacentHTML wird in allen aktuellen Browsern unterstützt .

div.insertAdjacentHTML( 'beforeend', str );

Live-Demo: http://jsfiddle.net/euQ5n/

Neil
quelle
1
@alex Es ist das gleiche Konzept: Eine HTML-Zeichenfolge analysieren und in das DOM einfügen. Die Funktionalität ist jedoch anders: innerHTMLSetzt die Zeichenfolge in das Element (ersetzt alle untergeordneten Elemente), während insertAdjacentHTMLsie (1) vor dem Element, (2) nach dem Element, (3) innerhalb des Elements vor dem ersten untergeordneten Element oder (4) platziert wird. innerhalb des Elements nach dem letzten Kind.
Šime Vidas
3
@alex insertAdjacentHTMList schneller als das Anhängen an innerHTML, da insertAdjacentHTMLdie vorhandenen untergeordneten Elemente des Elements nicht serialisiert und analysiert werden.
Hsivonen
2
Behält insertAdjacentHTMLauch die Werte geänderter Formularelemente bei, während das Anhängen an innerHTMLdas Element neu erstellt wird und der gesamte Formularkontext verloren geht.
Brandon Gano
20

Ist das akzeptabel?

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

jsFiddle .

Aber , Neil Antwort ist eine bessere Lösung.

Alex
quelle
1
@ Šime Arbeiten mit der DOM-API fühlt sich immer wie ein Hack an: P Möchten Sie den String lieber ohne unserialisieren innerHTML?
Alex
Nun ja, wenn es eine andere Möglichkeit gibt, den HTML-Parser des Browsers zu verwenden, würde ich gerne wissen ...
Šime Vidas
1
@ Šime - Ich denke, es gibt nur zwei Möglichkeiten, den HTML-Parser des Browsers zu verwenden: innerHTML und document.write. Und wenn Sie denken, innerHTML ist ein Hack ...
Alohci
@Alohci Es gibt noch einen anderen Weg : insertAdjacentHTML.
Šime Vidas
1
@ Šime - Danke. Ich habe die WHATWG-Version gefunden. Es befindet sich in der DOM-Analyse- und Serialisierungsspezifikation . Es zeigt an, dass es neben innerHTML und insertAdjacentHTML OuterHTML und, glaube ich, createContextualFragment gibt.
Alohci
16

Performance

AppendChild(E) ist mehr als 2x schneller als andere Lösungen auf Chrom und Safari, insertAdjacentHTML(F) ist auf Firefox am schnellsten. Das innerHTML=(B) (nicht mit +=(A) verwechseln ) ist die zweitschnelle Lösung in allen Browsern und viel praktischer als E und F.

Einzelheiten

Einrichtungsumgebung (2019.07.10) MacOs High Sierra 10.13.4 auf Chrome 75.0.3770 (64-Bit), Safari 11.1.0 (13604.5.6), Firefox 67.0.0 (64-Bit)

Geben Sie hier die Bildbeschreibung ein

  • Bei Chrome E ist (140.000 Operationen pro Sekunde) am schnellsten, B (47.000) und F (46.000) an zweiter Stelle, A (332) am langsamsten
  • auf Firefox ist F (94k) am schnellsten, dann ist B (80k), D (73k), E (64k), C (21k) am langsamsten A (466)
  • auf Safari ist E (207k) am schnellsten, dann B (89k), F (88k), D (83k), C (25k), am langsamsten ist A (509)

Sie können Test in Ihrem Gerät abspielen hier

Kamil Kiełczewski
quelle
12

Die Idee ist, innerHTMLein Zwischenelement zu verwenden und dann alle untergeordneten Knoten an die Stelle zu verschieben, über die Sie sie wirklich möchten 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);
}

Auf diese Weise wird vermieden, dass Ereignishandler gelöscht werden div#test, Sie können jedoch eine HTML-Zeichenfolge anhängen.

Chris Calo
quelle
3

Der richtige Weg ist mit insertAdjacentHTML. In Firefox vor 8 können Sie auf die Verwendung zurückgreifen, Range.createContextualFragmentwenn Ihre strkeine scriptTags enthält .

Wenn Ihr Tag Tags strenthält script, müssen Sie scriptElemente aus dem von zurückgegebenen Fragment entfernen, createContextualFragmentbevor Sie das Fragment einfügen. Andernfalls werden die Skripte ausgeführt. ( insertAdjacentHTMLMarkiert Skripte als nicht ausführbar.)

hsivonen
quelle
Vielen Dank für die Erwähnung createContextualFragment . Ich habe nach einer Möglichkeit gesucht, einige HTML-Includes mit Skripten nur dann auszuführen, wenn der Benutzer dem Setzen eines Cookies zustimmt.
Schliflo
3

Schneller Hack :


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

Anwendungsfälle :

1: Als HTML-Datei speichern und in Chrome, Firefox oder Edge ausführen. (IE wird nicht funktionieren)

2: Verwenden Sie in http://js.do

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

Aufgeschlüsselt mit Kommentaren:

<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>

Grund warum ich gepostet habe:

JS.do hat zwei Must-Haves:

  1. Keine automatische Vervollständigung
  2. Vertikaler Monitor freundlich

Zeigt jedoch keine console.log-Nachrichten an. Kam hierher auf der Suche nach einer schnellen Lösung. Ich möchte nur die Ergebnisse einiger Zeilen Scratchpad-Code sehen, die anderen Lösungen sind zu viel Arbeit.

JMI MADISON
quelle
1

Warum ist das nicht akzeptabel?

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

wäre das Lehrbuch, wie man es macht.

Nick Brunt
quelle
4
Es würde Event-Handler töten, die damit verbunden sind #test. Das ist im Allgemeinen nicht wünschenswert.
Alex
Interessant, dass es das tut. Scheint nicht wirklich logisch.
Nick Brunt
2
Es ist logisch, wenn Sie über die Serialisierung des HTML-Codes in einen String nachdenken und dann den HTML-Code zurücksetzen.
Alex
Ich denke, das JavaScript müsste erneut ausgeführt werden, um den Ereignishandler zurückzusetzen. Meinetwegen.
Nick Brunt
1
@Nick Sie möchten einen Teil des DOM nicht stringifizieren (serialisieren), nur damit Sie ihn mit einem anderen String verketten und dann das Ganze zurück in das DOM analysieren können. Wie Alex sagte, werden bei der Serialisierung (unter anderem) keine gebundenen Ereignishandler aufgezeichnet. Selbst wenn die Serialisierung alles erfassen könnte, würden Sie es trotzdem nicht tun wollen.
Šime Vidas
0

Dies kann lösen

 document.getElementById("list-input-email").insertAdjacentHTML('beforeend', '<div class=""><input type="text" name="" value="" class="" /></div>');
Rafael Senne
quelle
3
Willkommen beim Stapelüberlauf. Bitte erläutern Sie Ihren Code als Teil einer Antwort, um einen Kontext bereitzustellen, anstatt nur eine lange einzelne Codezeile einzufügen. Obwohl Sie es verstehen, verstehen andere möglicherweise nicht, was es tut.
loan.burger
0

InnerHTML löscht alle Daten wie Ereignisse für vorhandene Knoten

Kind mit firstChild anhängen fügt innerHTML nur das erste Kind hinzu. Zum Beispiel, wenn wir anhängen müssen:

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

Es wird nur Text1 angezeigt

Was ist damit:

Fügt innerHTML ein spezielles Tag hinzu, indem Sie ein Kind anhängen, und bearbeiten Sie dann OuterHTML, indem Sie das von uns erstellte Tag löschen. Ich weiß nicht, wie schlau es ist, aber es funktioniert für mich, oder Sie können OuterHTML in InnerHTML ändern, sodass keine Funktion zum Ersetzen verwendet werden muss

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>

Łukasz Szpak
quelle
0

Kürzeste - 18 Zeichen (nicht zu verwechseln +=(Erwähnung durch OP) mit =weiteren Details hier )

test.innerHTML=str

Kamil Kiełczewski
quelle