CSS, HTML und Javascript mit {stil}

cloneNode

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.

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.

HTML5 bringt ein template-Tag, das ganze Blöcke unsichtbar auf Vorrat für das Scripting bereit hält. Das template-Tag liefert die Vorlage für Blöcke, die cloneNode einfach und effektiv in das HTML-Dokument einhängen kann. IE unterstützt das template-Tag ab EDGE 14.

cloneNode()

Javascript node.cloneNode(deep)

cloneNode kopiert ein Element des DOM mitsamt childNodes, 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">
      <svg role="img" viewBox="0 0 741 444.5" height="100%" width="100%">
         …
      </svg>
   </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 var newNode = modal.cloneNode(true) geklont. Der geklonte Knoten existiert zunächst nur im Speicher.

if (document.querySelector(".modal") != null) {
   var modal = document.querySelector(".modal");
   modal.ontouch =
   modal.onclick = function (eve) {
      var newNode = modal.cloneNode(true);
      var div = document.createElement("div");
      div.classList.add("large");
      div.appendChild(newNode);
      modal.parentNode.insertBefore(div, modal);
   	
      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 this.parentNode.removeChild(document.querySelector(".large")) wieder bei einem Klick auf die Lightbox.

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.

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