cloneNode – Element kopieren / klonen

DOM-Elemente mit kopieren mit cloneNode und einfügen

cloneNode ist eine ausgesprochen effektive Technik, um ganze Strukturen in den DOM-Baum einzufügen – viel schneller als das Anlegen von Elementen mit createElement(). Analog kopiert importNode Elemente aus einem anderen Dokument.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

HTML template-Element

Geklonte Elemente sind im Quellcode des Dokuments nicht sichtbar und bleiben den Suchmaschinen verborgen. Sie wurden lediglich als Elemente ins DOM des Browsers eingefügt, nicht aber als Markup und Text in den Quelltext geschrieben.

HTML-template-Tags halten ganze HTML-Blöcke für das Scripting unsichtbar auf Vorrat bereit und liefern so die Vorlage für Blöcke, die cloneNode einfach und effektiv in das HTML-Dokument einhängen kann. Microsoft unterstützt <template> ab EDGE 14.

<template id="template">
	<div class="elem">
		<span></span>
	</div>
</template>
let node = document.querySelector ("#template");
var clone = node.cloneNode (deep);

cloneNode ()

cloneNode kopiert ein Element des DOM mitsamt seinen Kind-Elementen, um die Struktur des Dokuments zu ändern. Die Kopie kann an einer anderen Stelle des DOM aufgehangen werden.

Der Parameter deep ist vom Typ Boolean und gibt an, ob der Knoten mit all seinen Elementen geklont werden soll (deep = true). Event Listener, die auf Events des Elements warten, werden allerdings auch mit deep = true nicht mitgeliefert.

Ein Klick oder Touch auf das Bild erzeugt einen Overlay oder eine Lightbox, die das Bild größer auf dunklem Hintergrund zeigt. Auch bei komplexen und großen Elementen mit vielen Unterelementen erzeugt cloneNode die Kopie innerhalb eines Augenblicks.

<div class="overlay">
	<div class="modal">
		<figure>
			<img loading="lazy" src="orange-citrus-cherry.svg" width="741" height="444" alt="…">
			<figcaption>Klick oder Touch zum Vergrößern</figcaption>
		</figure>
	</div>
</div>

Die Bedingung der Abfrage if (document.querySelector(".modal") != null) prüft, ob ein Element mit class="modal" existiert. Der Check verhindert Javascript-Fehler, wenn die Struktur des HTML-Elements eines Tages geändert werden sollte. Wenn ein Element mit class="modal" existiert, wird das komplette Element mit let newNode = modal.cloneNode(true) geklont. Der geklonte Knoten existiert zunächst nur im Speicher.

if (document.querySelector(".modal") != null) {
   document.querySelector(".modal").addEventListener ("click", function (eve) {
      const newNode = this.cloneNode (true);
      const div = document.createElement ("div");

      div.classList.add ("large");
      div.appendChild(newNode);
      this.parentNode.insertBefore (div, this);

      div.onclick = function () {
         this.parentNode.removeChild(document.querySelector (".large"));
      }
      eve.preventDefault();
   });
}

Erst wenn ein neues Element mit modal.parentNode.insertBefore(div, modal) in das DOM eingefügt wird, entsteht der Overlay – die klassische Lightbox. Am Ende entfernt ein Klick auf die Lightbox den Overlay:

this.parentNode.removeChild(document.querySelector(".large"))

cloneNode ist schnell und perfekt geeignet, um große Bereich des DOMs zu kopieren. Hinterher kann das Original mit removeChild gelöscht werden.

cloneNode und EventListener

cloneNode() kopiert keine Event Listener. Keine Technik des DOM übernimmt Event Listener, die einzigen Optionen sind:

  • Den Event Listener manuell auf den geklonten Knoten setzen.
  • Event-Delegation: Den Event Listener auf einen Node setzen, der sowohl das Original als auch die Kopie enthält.
  • Ein Wrapper für Node.addEventListener – so macht es clone() in jQuery, wo man einen Node mitsamt Event Listener kopieren kann (.clone( [withDataAndEvents ] )).

importNode

importNode() importiert Element von einem anderen Dokument (z.B. aus einem iframe). Das Element wird nicht aus dem anderen Dokument gelöscht.

let mynode = document.querySelector("iframe").contentDocument.getElementById ("foo");
let newNode = document.importNode(mynode, true);