Vergleich von Methoden zum Anhängen und Einfügen mit JavaScript

Avatar of Eric Markfield
Eric Markfield am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Nehmen wir an, wir möchten etwas nach dem anfänglichen Laden zu einer Webseite hinzufügen. JavaScript bietet uns eine Vielzahl von Werkzeugen. Vielleicht haben Sie einige davon verwendet, wie append, appendChild, insertAdjacentHTML oder innerHTML.

Das Schwierige beim Anhängen und Einfügen von Dingen mit JavaScript liegt weniger in den Werkzeugen, die es bietet, sondern darin, welches Werkzeug wann verwendet werden soll und wie jedes einzelne funktioniert.

Lassen Sie uns versuchen, die Dinge zu klären.

Sehr kurzer Kontext

Es kann hilfreich sein, ein wenig Hintergrund zu besprechen, bevor wir beginnen. Auf einfachster Ebene ist eine Website eine HTML-Datei, die von einem Server an einen Browser heruntergeladen wird.

Ihr Browser wandelt die HTML-Tags in Ihrer HTML-Datei in eine Reihe von Objekten um, die mit JavaScript manipuliert werden können. Diese Objekte bilden einen Document Object Model (DOM)-Baum. Dieser Baum ist eine Reihe von Objekten, die als Eltern-Kind-Beziehungen strukturiert sind.

Im DOM-Jargon werden diese Objekte als Knoten oder genauer gesagt als HTML-Elemente bezeichnet.

<!-- I'm the parent element -->
<div>
  <!-- I'm a child element -->
  <span>Hello</span>
</div>

In diesem Beispiel ist das HTML-span-Element das *Kind* des div-Elements, das der *Elternteil* ist.

Und ich weiß, dass einige dieser Begriffe seltsam und möglicherweise verwirrend sind. Wir sagen „Knoten“, aber manchmal sagen wir stattdessen auch „Element“ oder „Objekt“. Und in einigen Fällen beziehen sie sich auf dasselbe, je nachdem, wie spezifisch wir sein wollen.

Zum Beispiel ist ein „Element“ eine spezielle Art von „Knoten“, so wie ein Apfel eine spezielle Art von Frucht ist.

Wir können diese Begriffe von allgemein bis spezifisch ordnen: ObjektKnotenElementHTML-Element

Das Verständnis dieser DOM-Elemente ist wichtig, da wir mit ihnen interagieren werden, um Dinge mit JavaScript nach dem ersten Laden der Seite hinzuzufügen und anzuhängen. Tatsächlich wollen wir damit beginnen.

Setup

Diese Anhänge- und Einfügemethoden folgen meist diesem Muster

Element.append_method_choice(stuff_to_append)

Auch hier ist ein Element lediglich ein Objekt im DOM-Baum, das etwas HTML darstellt. Zuvor erwähnten wir, dass der Zweck des DOM-Baums darin besteht, uns eine bequeme Möglichkeit zu geben, mit HTML über JavaScript zu interagieren.

Wie können wir also mit JavaScript ein HTML-Element abrufen?

Abfragen des DOM

Nehmen wir an, wir haben folgendes kleines bisschen HTML

<div id="example" class="group">
  Hello World
</div>

Es gibt ein paar gängige Möglichkeiten, das DOM abzufragen

// Query a specific selector (could be class, ID, element type, or attribute):
const my_element1 = document.querySelector('#example')

// Query an element by its ID:
const my_element2 = document.getElementbyId('example')

// Query an element by its class:
const my_element3 = document.getElementsbyClassName('group')[0] 

In diesem Beispiel fragen alle drei Zeilen dasselbe ab, suchen es aber auf unterschiedliche Weise. Eine schaut auf beliebige der CSS-Selektoren des Elements; eine schaut auf die ID des Elements; und eine schaut auf die Klasse des Elements.

Beachten Sie, dass die Methode getElementbyClass ein Array zurückgibt. Das liegt daran, dass sie mehrere Elemente im DOM abgleichen kann und die Speicherung dieser Übereinstimmungen in einem Array sicherstellt, dass alle berücksichtigt werden.

Was wir anhängen und einfügen können

// Append Something
const my_element1 = document.querySelector('#example')
my_element1.append(something)

In diesem Beispiel ist something ein Parameter, der Zeug darstellt, das wir an das Ende des abgeglichenen Elements anhängen möchten (d. h. anfügen).

Wir können nicht einfach beliebige Dinge an beliebige Objekte anhängen. Die append-Methode erlaubt uns nur, entweder einen Knoten oder einfachen Text an ein Element im DOM anzuhängen. Aber einige andere Methoden können auch HTML an DOM-Elemente anhängen.

  1. Knoten werden entweder mit document.createElement() in JavaScript erstellt oder mit einer der Abfragemethoden ausgewählt, die wir im letzten Abschnitt betrachtet haben.
  2. Einfacher Text ist eben Text. Er ist einfacher Text in dem Sinne, dass er keine HTML-Tags oder Formatierungen mit sich führt (z. B. Hallo).
  3. HTML ist ebenfalls Text, aber im Gegensatz zu einfachem Text wird er beim Hinzufügen zum DOM als Markup geparst (z. B. <div>Hallo</div>).

Es könnte hilfreich sein, genau aufzuschlüsseln, welche Parameter von welchen Methoden unterstützt werden

MethodeKnotenHTML-TextText
appendJaNeinJa
appendChildJaNeinNein
insertAdjacentHTMLNeinJaJa1
innerHTML2NeinJaJa
1 Dies funktioniert, aber insertAdjacentText wird empfohlen.
2 Anstatt traditioneller Parameter zu verwenden, wird innerHTML wie folgt verwendet: element.innerHTML = 'HTML-String'

Wie man wählt, welche Methode man verwendet

Nun, es hängt wirklich davon ab, was Sie anhängen möchten, ganz zu schweigen von bestimmten Eigenheiten des Browsers, die zu berücksichtigen sind.

  • Wenn Sie vorhandenes HTML haben, das an Ihr JavaScript gesendet wird, ist es wahrscheinlich am einfachsten, mit Methoden zu arbeiten, die HTML unterstützen.
  • Wenn Sie neues HTML in JavaScript erstellen, kann die Erstellung eines Knotens mit viel Markup umständlich sein, während HTML weniger ausführlich ist.
  • Wenn Sie sofort Ereignis-Listener anhängen möchten, sollten Sie mit Knoten arbeiten, da wir addEventListener auf Knoten und nicht auf HTML aufrufen.
  • Wenn Sie nur Text benötigen, ist jede Methode, die einfache Textparameter unterstützt, in Ordnung.
  • Wenn Ihr HTML potenziell nicht vertrauenswürdig ist (d. h. es stammt von Benutzereingaben, z. B. einem Kommentar zu einem Blogbeitrag), sollten Sie bei der Verwendung von HTML vorsichtig sein, es sei denn, es wurde bereinigt (d. h. der schädliche Code wurde entfernt).
  • Wenn Sie Internet Explorer unterstützen müssen, dann ist die Verwendung von append ausgeschlossen.

Beispiel

Nehmen wir an, wir haben eine Chat-Anwendung und möchten einen Benutzer, Dale, zu einer Freundesliste hinzufügen, wenn er sich anmeldet.

<!-- HTML Buddy List -->
<ul id="buddies">
  <li><a>Alex</a></li>
  <li><a>Barry</a></li>
  <li><a>Clive</a></li>
  <!-- Append next user here -->
</ul>

Hier ist, wie wir dies mit jeder der oben genannten Methoden erreichen würden.

append

Wir müssen ein Knotenobjekt erstellen, das sich in <li><a>Dale</a></li> übersetzt.

const new_buddy = document.createElement('li')
const new_link = document.createElement('a')

const buddy_name = "Dale"

new_link.append(buddy_name) // Text param
new_buddy.append(new_link) // Node param

const list = document.querySelector('#buddies')
list.append(new_buddy) // Node param

Unser endgültiges append platziert den neuen Benutzer am Ende der Freundesliste, direkt vor dem schließenden </ul>-Tag. Wenn wir den Benutzer lieber am Anfang der Liste platzieren möchten, könnten wir stattdessen die Methode prepend verwenden.

Sie haben vielleicht bemerkt, dass wir append auch verwenden konnten, um unser <a>-Tag mit Text wie folgt zu füllen

const buddy_name = "Dale"
new_link.append(buddy_name) // Text param

Dies unterstreicht die Vielseitigkeit von append.

Und nur um es noch einmal hervorzuheben, append wird in Internet Explorer nicht unterstützt.

appendChild

appendChild ist eine weitere JavaScript-Methode zum Anhängen von Dingen an DOM-Elemente. Sie ist etwas eingeschränkt, da sie nur mit Knotenobjekten funktioniert, sodass wir Hilfe von textContent (oder innerText) für unsere reinen Textanforderungen benötigen.

Beachten Sie, dass appendChild im Gegensatz zu append in Internet Explorer unterstützt wird.

const new_buddy = document.createElement('li')
const new_link = document.createElement('a')

const buddy_name = "Dale"

new_link.textContent = buddy_name
new_buddy.appendChild(new_link) // Node param

const list = document.querySelector('#buddies')
list.appendChild(new_buddy) // Node param

Bevor wir weitermachen, betrachten wir ein ähnliches Beispiel, aber mit stärkerem Markup.

Nehmen wir an, das HTML, das wir anhängen wollten, sah nicht aus wie <li><a>Dale</a></li>, sondern eher wie

<li class="abc" data-tooltip="Click for Dale">
  <a id="user_123" class="def" data-user="dale">
    <img src="images/dale.jpg" alt="Profile Picture"/>
    <span>Dale</span>
  </a>
</li>

Unser JavaScript würde ungefähr so aussehen

const buddy_name = "Dale"

const new_buddy = document.createElement('li')
new_buddy.className = 'abc'
new_buddy.setAttribute('data-tooltip', `Click for ${buddy_name}`)

const new_link = document.createElement('a')
new_link.id = 'user_123'
new_link.className = 'def'
new_link.setAttribute('data-user', buddy_name)

const new_profile_img = document.createElement('img')
new_profile_img.src = 'images/dale.jpg'
new_profile_img.alt = 'Profile Picture'

const new_buddy_span = document.createElement('span')
new_buddy_span.textContent = buddy_name

new_link.appendChild(new_profile_img) // Node param
new_link.appendChild(new_buddy_span) // Node param
new_buddy.appendChild(new_link) // Node param

const list = document.querySelector('#buddies')
list.appendChild(new_buddy) // Node param

Es gibt keinen Grund, all das obige JavaScript zu befolgen – der Punkt ist, dass die Erstellung großer Mengen HTML in JavaScript ziemlich umständlich werden kann. Und dem kann man nicht entkommen, wenn wir append oder appendChild verwenden.

In diesem Szenario mit starkem Markup wäre es schön, unser HTML einfach als Zeichenkette schreiben zu können, anstatt eine Reihe von JavaScript-Methoden zu verwenden…

insertAdjacentHTML

insertAdjacentHTML ist wie append, da es auch Dinge zu DOM-Elementen hinzufügen kann. Ein Unterschied ist jedoch, dass insertAdjacentHTML diese Dinge an einer bestimmten Position relativ zum abgeglichenen Element einfügt.

Und es funktioniert zufällig mit HTML. Das bedeutet, wir können tatsächliches HTML in ein DOM-Element einfügen und genau bestimmen, wo wir es mit vier verschiedenen Positionen haben wollen

<!-- beforebegin -->
<div id="example" class="group">
  <!-- afterbegin -->
  Hello World
  <!-- beforeend -->
</div>
<!-- afterend -->

So können wir die Idee, unser HTML zu „appenden“, ungefähr nachbilden, indem wir es an der Position beforeend des #buddies-Selectors einfügen

const buddy_name = "Dale"

const new_buddy = `<li><a>${buddy_name}</a></li>`
const list = document.querySelector('#buddies')
list.insertAdjacentHTML('beforeend', new_buddy)

Erinnern Sie sich an die Sicherheitsbedenken, die wir zuvor erwähnt haben. Wir sollten niemals von einem Endbenutzer eingegebenes HTML einfügen, da wir uns sonst anfällig für Cross-Site-Scripting-Schwachstellen machen würden.

innerHTML

innerHTML ist eine weitere Methode zum Einfügen von Dingen. Dennoch wird sie zum Einfügen nicht empfohlen, wie wir sehen werden.

Hier ist unsere Abfrage und das HTML, das wir einfügen möchten

const buddy_name = "Dale"
const new_buddy = `<li><a>${buddy_name}</a></li>`
const list = document.querySelector('#buddies')  
list.innerHTML += new_buddy

Anfänglich scheint das zu funktionieren. Unsere aktualisierte Freundesliste sieht im DOM so aus

<ul id="buddies">
  <li><a>Alex</a></li>
  <li><a>Barry</a></li>
  <li><a>Clive</a></li>
  <li><a>Dale</a></li>
</ul>

Das ist es, was wir wollen! Aber es gibt eine Einschränkung bei der Verwendung von innerHTML, die uns daran hindert, Ereignis-Listener für Elemente innerhalb von #buddies zu verwenden, aufgrund der Natur von += in list.innerHTML += new_buddy.

Sie sehen, A += B verhält sich genauso wie A = A + B. In diesem Fall ist A unser vorhandenes HTML und B ist das, was wir ihm hinzufügen. Das Problem ist, dass dies zu einer Kopie des vorhandenen HTML mit dem zusätzlich eingefügten HTML führt. Und Ereignis-Listener können keine Kopien überwachen. Das bedeutet, wenn wir auf eines der <a>-Tags in der Freundesliste für ein Klickereignis hören wollen, verlieren wir diese Fähigkeit mit innerHTML.

Also, nur eine Warnung.

Demo

Hier ist eine Demo, die alle von uns behandelten Methoden zusammenfasst. Das Klicken auf die Schaltfläche jeder Methode fügt „Dale“ als Element zur Freundesliste hinzu.

Öffnen Sie dazu auch die DevTools und sehen Sie, wie das neue Listenelement zum DOM hinzugefügt wird.

Zusammenfassung

Hier ist ein allgemeiner Überblick über unseren Stand, wenn wir Dinge in das DOM anhängen und einfügen. Betrachten Sie es als Spickzettel für den Fall, dass Sie Hilfe bei der Entscheidung benötigen, welche Methode Sie verwenden sollen.

MethodeKnoten
HTML-TextText
Internet Explorer?Ereignis-ListenerSicher?
HTML-Templating
appendJaNeinJaNeinBewahrtJaMittel
appendChildJaNeinNeinJaBewahrtJaMittel
insertAdjacentHTMLNeinJaJa1JaBewahrtVorsichtigEinfach
innerHTML2NeinJaJaJaVerliertVorsichtigEinfach
1 Dies funktioniert, aber insertAdjacentText wird empfohlen.
2 Anstatt traditioneller Parameter zu verwenden, wird innerHTML wie folgt verwendet: element.innerHTML = 'HTML-String'

Wenn ich das alles in ein paar Empfehlungen zusammenfassen müsste

  • Die Verwendung von innerHTML zum Anhängen wird nicht empfohlen, da sie Ereignis-Listener entfernt.
  • append funktioniert gut, wenn Sie die Flexibilität der Arbeit mit Knotenelementen oder reinem Text mögen und Internet Explorer nicht unterstützen müssen.
  • appendChild funktioniert gut, wenn Sie gerne (oder müssen) mit Knotenelementen arbeiten und volle Browserabdeckung wünschen.
  • insertAdjacentHTML ist gut, wenn Sie HTML generieren müssen und eine genauere Kontrolle darüber wünschen, wo es im DOM platziert wird.

Tiefer graben

Die oben genannten Methoden werden häufig verwendet und sollten die Mehrheit Ihrer Anwendungsfälle abdecken.

Das gesagt, es gibt noch einige zusätzliche Anhänge-/Einfügemethoden, falls Sie neugierig sind

Letzter Gedanke und ein kurzer Hinweis :)

Dieser Beitrag wurde durch reale Probleme inspiriert, auf die ich kürzlich bei der Entwicklung einer Chat-Anwendung gestoßen bin. Wie Sie sich vorstellen können, ist eine Chat-Anwendung auf viel Anhängen/Einfügen angewiesen – Leute, die online kommen, neue Nachrichten, Benachrichtigungen usw.

Diese Chat-Anwendung heißt Bounce. Es ist ein Peer-to-Peer-Lern-Chat. Angenommen, Sie sind ein JavaScript-Entwickler (unter anderem), haben Sie wahrscheinlich etwas zu lehren! Und Sie können etwas zusätzliches Geld verdienen.

Wenn Sie neugierig sind, hier ist ein Link zur Homepage oder mein Profil auf Bounce. Prost!