CSS, HTML und Javascript mit {stil}

appendChild, replaceChild, removeChild, insertBefore

getElementById getElementsByName getElementByTagName

Javascript replaceChild, removeChild, appendChild und insertBefore ändern die Struktur des DOM-Baums: Sie operieren auf Knoten, fügen Knoten in den Dokumentenbaum ein, kopieren Knoten und entfernen ganze Äste aus dem Baum.

Das Nachladen von Bildern oder ganzen Blöcken mit Inhalt sorgt für schnelle Ladezeiten von Webseiten. Ob die Daten mit JSON geholt werden oder aus der Datenbank kommen: Wenn sie als Elementknoten in die HTML-Seite eingebunden werden, sind die nachgeladenen Daten vollwertige Objekte des DOM.

In der Konsole sehen wir neue Nodes im Quelltext. Das ist der Unterschied zum Einfügen mit innerHTML: innerHTML kann zwar HTML-Tags einsetzen, die vom Browser auch mit CSS versorgt werden, aber im DOM existieren diese Elemente nicht.

replaceChild()

Javascript node.replaceChild(newChild, oldChild) ersetzt unterhalb des Knotens node den Knoten oldChild durch den Knoten newChild. Der ersetzte Knoten wird automatisch gelöscht.

Dabei können sowohl der ersetzte Knoten als auch der neue Knoten komplette Blöcke mitsamt beliebig vielen Kindknoten sein. Der neue Knoten kann mit cloneNode aus dem Dokument kopiert werden oder kann ein neu erzeugter Knoten sein.

  • Montag
  • Dienstag
  • Mittwoch
<ul id="aList">
   <li>Montag</li>
   <li>Dienstag</li>
   <li>Mittwoch</li>
</ul>

Um den Knoten mit der id aList durch den neu erzeugten Knoten newNode zu ersetzen, muss newNode unterhalb des parentNode des alten Knotens eingehangen werden: oldNode.parentNode.replaceChild(newNode, oldNode);.

var old = document.querySelector('#aList');
var new = document.createElement('p');
var newText = document.createTextNode('An drei Tagen in der Woche');
new.appendChild(newText);
old.parentNode.replaceChild(new, old);
new.setAttribute('id','aList');

Wenn das Skript nach dem Ersetzen des alten Knotens erneut angestoßen wird, würde es einen Fehler erzeugen, weil das Element mit id="aList" nicht mehr existiert. Darum bekommt das neu erzeugte Element die ID aList.

appendChild()

Javascript node.appendChild(child) Fügt dem Knoten node ein Kind als childNode hinzu. Wenn node schon Kinder hat, wird childNode hinter die älteren Kinder gehangen. node muss ein Elementknoten sein, Textknoten können keine Kinder haben.

Das Nachladen von Bildern mit newImage() und appendChild() sorgt dafür, dass Seiten beim Besucher schneller geladen werden.

document.getElementById('append').onclick = function () {
    if (document.getElementById('toAppend')) {
        var images = new Array();
        images = ['bird1.png','bird2.png','bird3.png'];
        for (i=0; i<images.length; i++) {
            var img = new Image();
            img.src = images[i];
            document.getElementById('toAppend').appendChild(img);
        }
    }
}

Objekte, die mit appendChild() in das DOM gebunden werden, sind vollwertige Objekte im DOM-Baum und können später über Javascript-Funktionen angesprochen werden. Das unterscheidet appendChild und replaceChild von der Funktion innerHTML.

<div id="fix">
</div>
function append() {
   var fixed = document.getElementById('fix');
   var newP = document.createElement('p');
   var newText = document.createTextNode('Neuer Absatz');
   fixed.appendChild(newP);
   newP.appendChild(newText);
}
getElementById4.png
  • var fixed = document.getElementById('fix'); findet das Element mit dem id-Attribut 'fix' und setzt die Variable fixed als Referenz auf das Objekt.
  • var newP = document.createElement('p'); erzeugt einen neuen Elementknoten vom Typ p.
  • var newText = document.createTextNode('Neuer Absatz'); erzeugt einen neuen Textknoten und setzt die Variable newText als Referenz auf den Textknoten.
  • fixed.appendChild(newP); fügt den Knoten newP als Kindknoten an den Knoten fixed an.
  • newP.appendChild(newText); fügt den Textknoten an den Knoten newP an.

Das Einfügen neuer Knoten mit appendChild() in den leeren Platzhalter <div id="fix"> ist einfach, aber Platzhalter sind Ballast für das Markup und was passiert, wenn ein Skript etwas mit vielen, vielleicht sogar dynamisch erzeugten Elementen anstellen soll?

Zudem hat sich das Skript darauf verlassen, dass der Platzhalter <div id="fix"> tatsächlich vorhanden ist – eine der vorrangigsten Fehlerquellen bei der Programmierung auf dem DOM: Wenn der Platzhalter nicht da ist, passiert beim Klick auf appendChild() nichts und nur eine neue Fehlermeldung füllt die Javascript-Konsole.

insertBefore ()

appendChild() ist schnell und einfach, wenn Inhalte am Ende eines Elements eingefügt werden. Javascript insertBefore() funktioniert ähnlich wie appendChild(), aber mit insertBefore() kann ein Element an jede beliebige Stelle platziert werden.

node.insertBefore ( newchild, oldchild ) fügt unterhalb von node einen Knoten newchild vor oldchild ein.

<div>       <---------------+
    <div> … </div>          |
    <figure> … </figure>    +-- parentNode
    <div> … </div>          |
</div>      <---------------+

var heading = document.createElement('h3');
var figure = document.querySelector ('figure');
figure.parentNode.insertBefore( heading, figure);

Mindestens ebenso oft wie das Einfügen neuer Knoten vor einem vorhandenen Knoten ist das Einfügen eines Knotens nach einem Element gefragt – aber eine passende Javascript-Funktion gibt es dafür nicht. insertBehind simmuliert die fehlende Methode mit der Hilfe der Eigenschaft nextSibling.

Das Script nutzt nextSibling als Punkt zum Einhängen des neuen Elements. Falls kein nextSibling existiert, darf der Knoten ohne jegliches Federlesen als letztes Kind an den Elternknoten gehangen werden: node.parentNode.appendChild();.

"use strict";
document.querySelector('button').onclick = function () {
	var figure = document.querySelector('.demohase');
	var caption = document.createElement ('p');
	caption.innerHTML = "Kein Igel in Sicht?";
	if (figure.nextSibling) {
		figure.parentNode.insertBefore( caption, figure.nextSibling);
	} else {
		figure.parentNode.appendChild(caption);
	}
}

removeChild()

Javascript node.removeChild(oldChild) entfernt den Knoten oldChild unterhalb des Knotens node.

Dabei kann der Knoten oldChild ein vollständiges Fragment mit eigenen Kindknoten sein – removeChild entfernt den kompletten Block mit sämtlichen Unterknoten.

<figure id="figure" style="background: wheat;">
   <div id="birds" >
      <img src="bird6.png" alt="" width="190" height="121" />
      <img src="bird5.png" alt="" width="190" height="121" />
      <img src="bird4.png" alt="" width="190" height="121" />
   </div>
   <button id="removeBirds">Bilder löschen</button>
</figure>
…
document.getElementById('removeBirds').onclick = function () {
    if (document.getElementById('birds')) {
        var birds = document.getElementById('birds');
        birds.parentNode.removeChild(birds);
    }
}

Der Knoten wird anhand seines id-Attributs birds identifiziert und schnell und schmerzlos mitsamt seinem Kindknoten aus seinem Elternknoten entfernt: myNode.parentNode.removeChild(birds);. Damit ein erneuter Aufruf nicht zu einem Skriptfehler führt, weil der Knoten mit der id birds nicht mehr gefunden wird, prüft die erste Anweisung, ob der Knoten mit der id birds existiert (if (document.getElementById('birds'))).