JavaScript/DOM/Element/innerHTML

Aus SELFHTML-Wiki
< JavaScript‎ | DOM‎ | Element
Wechseln zu: Navigation, Suche

Die Eigenschaft Element.innerHTML liest und speichert den Inhalt eines HTML-Elements in Form von HTML-Quellcode. Wenn das Element Kindelemente besitzt, finden Sie in innerHTML das zugehörige Markup vor. Wenn Sie an innerHTML etwas zuweisen, wird der zugewiesene String als HTML interpretiert und in DOM-Strukturen umgewandelt.

Syntax

const content = element.innerHTML;

  • Der gesamte Inhalt von element wird der Konstanten content zugewiesen.

element.innerHTML = content;

  • Der evtl. vorhandene Inhalt des Elements wird durch den Wert von content ersetzt.


Anwendungsbeispiel

document
	.getElementById('button')
	.addEventListener('click',changeHTMLContent);

function changeHTMLContent() {
	document
		.getElementById('absatz')
		.innerHTML = "neuer <b>fetter</b> Text";
}
Das Beispiel enthält einen Textabsatz und einen Button. Beim Anklicken des Buttons wird die Funktion changeHTMLContent() aufgerufen. Diese Funktion weist dem Absatz mit der id="absatz" für die Eigenschaft innerHTML eine Zeichenkette mit einem HTML-Fragment zu. Der alte Inhalt dieses Elements wird entfernt, der neue Inhalt besteht aus drei DOM-Knoten: ein Textknoten mit dem Inhalt "neuer ", ein <b>-Elementknoten mit dem Inhalt "fetter" und ein weiterer Textknoten mit dem Inhalt " Text". Sobald das Script fertig ist, zeigt der Browser den geänderten Inhalt an. Durch das <b>-Element wird das Wort „fetter“ hervorgehoben.

Die Eigenschaft innerHTML sollten Sie nicht direkt beim Einlesen der HTML-Datei anwenden, sondern immer erst abhängig von Aktionen wie Verweisklicks oder Button-Klicks oder mit einem setTimeout() von einigen Sekunden davor.

Vermeiden Sie es, in einer Schleife mehrere HTML-Fragmente an innerHTML anzuhängen. Einen besseren Weg beschreiben wir im Abschnitt Performance. Sie müssen es auch vermeiden, unvollständige HTML-Fragmente zuzuweisen. Das diskutieren wir im Abschnitt zur unerwünschten Fehlerbehandlung.

Sicherheitsrisiken

Sie können mit innerHTML das DOM außerhalb des Elements, dem Sie etwas zuweisen, nicht beeinflussen (siehe auch den folgenden Abschnitt zur Fehlerbehandlung). Wenn Sie aber eine Zeichenkette zuweisen, die Sie von anderswo erhalten haben, können sich darin Inhalte befinden, die die Privatsphäre des Benutzers gefährden. <script>-Elemente lassen SIch mit innerHTML zwar nicht erzeugen,[1] es genügt aber auch ein onclick-Attribut, in dem sich Script befindet.

Verborgenes Script
const skript = 'alert("Mistkerl")';
const gruss = "Mit <span onclick='"+skript+"'>freundlichen Grüßen</span>";

document.querySelector("#gruss") = gruss;

In diesem Beispiel ist der „nette“ Gruß offensichtlich, aber was, wenn Sie gruss aus einer Datenbank erhalten haben? Zuweisungen an innerHTML sollten nur erfolgen, wenn Sie den zugewiesenen Inhalt unter Kontrolle haben. Fremdinhalte müssen maskiert werden – das Mindeste ist, < durch &lt; zu ersetzen.

Wenn Sie lediglich Text zuweisen wollen, verwenden Sie die textContent-Eigenschaft. Hier wird kein HTML interpretiert und Überlegungen zur Sicherheit sind überflüssig. Die früher vom Internet Explorer verwendete Eigenschaft innerText ist ebenfalls möglich.

unerwünschte Fehlerbehandlung im Browser

Sobald Sie die innerHTML-Eigenschaft eines Elements verändern, wird der von Ihnen veränderte Inhalt sofort vom Javascript-Interpreter an den Teil der Browserengine weitergegeben, der HTML interpretiert. Das bedeutet insbesondere, dass Ihr Quellcode auch durch die Fehlerbehandlung und vor allem die Fehlerkorrekturen des HTML-Interpreters beeinflusst wird, was zu unvorhergesehenen Effekten führen kann. Ein automatisches Schließen von HTML-Elementen durch den Browser ist ein offensichtliches Beispiel, das zu unerwünschten Ergebnissen führen kann:

function Zählen () {
  document.getElementById("Liste").innerHTML = "";

  for (let i = 1; i <= 10; i++) {
    document.getElementById("Liste").innerHTML += "<li>";
    document.getElementById("Liste").innerHTML += i;
    document.getElementById("Liste").innerHTML += "</li>";
  }
}

function Zählen2 () {
  document.getElementById("Liste").innerHTML = "";

  for (let i = 1; i <= 10; i++) {
    document.getElementById("Liste").innerHTML += "<li>" + i + "</li>";
  }
}
Auf den ersten Blick scheint es keinen Unterschied zwischen den Funktionen zu geben. Die beiden Funktionen unterscheiden sich jedoch dadurch, dass der zu ändernde Quellcode in der ersten Variante Stück für Stück zusammengesetzt wird, während der hinzuzufügende Quellcode in der zweiten Variante zuerst zusammengefügt und dann eingesetzt wird. Im ersten Fall sorgt die Fehlerbehandlung des Browsers dafür, dass schon nach dem ersten Einfügen die vermeintlich fehlerhaften (weil nicht geschlossenen) li-Elemente zunächst direkt automatisch geschlossen werden - dadurch landet der Text, der als Inhalt für die li-Elemente gedacht war, hinter den li-Elementen statt darin, denn die li-Elemente wurden zu diesem Zeitpunkt schon durch den Browser geschlossen.
Empfehlung: Achten Sie darauf, dass der veränderte Quelltext, den Sie via innerHTML zuweisen, zu jedem Zeitpunkt für sich selbst vollständig valide ist und dadurch keine unerwünschte Fehlerbehandlung im Browser auslösen kann.

Performance

Das Beispiel im Fehlerbehandlungsabschnitt zeigt eine typische Performancefalle von innerHTML. Wenn Sie mit elem.innerHTML+="..." mehrere HTML-Fragmente zusammensetzen, muss jedesmal der entsprechende Teilbaum des DOM zunächst in HTML Quelltext umgewandelt und nach der Zuweisung wieder in HTML Elementobjekte übersetzt werden.

Wenn Sie mit HTML-Quelltext arbeiten möchten, verwenden Sie besser die Methode insertAdjacentHTML. Hier muss lediglich das neue Stück HTML interpretiert werden und das bestehende DOM kann bleiben, wie es ist. Das ist vor allem dann wichtig, wenn im existierenden DOM bereits Eventhandler registriert wurden. Eine Zuweisung an innerHTML würde sie zerstören.

Das Beispiel von vorhin sähe dann so aus:

Aufbau einer Liste mit insertAdjacentHTML()
function Zählen2 () {
  const liste = document.getElementById("Liste");

  for (let i = 1; i <= 10; i++) {
    liste.insertAdjacentHTML("beforeend", "<li>" + i + "</li>");
  }
}

An Stelle von insertAdjacentHTML können Sie das HTML auch zunächst in einer Zeichenkette oder in einem Array vorbereiten und dann auf einmal zuweisen:

Zusammensetzen des HTML in einem Array
function Zählen2 () {
  const listenelemente = [];
  for (let i = 1; i <= 10; i++) {
    listenelemente.push("<li>" + i + "</li>");
  }
  document.getElementById("Liste").innerHTML = listenelemente.join('');
}

Dieses Beispiel verwendet die push-Methode, um an ein Array HTML-Fragmente anzuhängen und setzt sie dann mittels join zu einem String zusammen.

Quellen

  1. MDN: element.innerHTML Security considerations

Weblinks