Start · Sprachen · JavaScript · Referenz · Range.cloneContents()

Range.cloneContents()

Methode

Kopiert den Inhalt eines <code>Range</code> samt aller enthaltenen Knoten in ein neues <code>DocumentFragment</code>, ohne das Dokument zu verändern.

seit JavaScript Baseline: alle Browser (DOM Level 2) Kategorie: webapi

Signatur

Range.prototype.cloneContents()

Beschreibung

cloneContents() erzeugt eine tiefe Kopie aller Knoten, die ganz oder teilweise im Bereich liegen, und gibt sie als DocumentFragment zurück. Das Originaldokument bleibt unverändert. Genau darin unterscheidet sich die Methode von extractContents(): Diese verschiebt die Knoten und entfernt sie dabei aus dem Dokument.

Beginnt oder endet der Bereich mitten in einem Element, werden die angeschnittenen Elternelemente teilweise geklont. Die Kopie enthält dann nur das Start- bzw. End-Tag und den Teil des Inhalts, der tatsächlich im Bereich liegt. Teilweise ausgewählte Textknoten werden auf den ausgewählten Text zugeschnitten. So entsteht immer ein Fragment mit gültiger Baumstruktur.

Typische Einsatzfälle:

  • die Benutzerauswahl (Selection.getRangeAt(0)) als HTML auslesen, etwa für eigene Kopier- oder Zitierfunktionen,
  • Vorschauen oder Auszüge aus einem Dokumentabschnitt erzeugen,
  • Inhalte in einen anderen Container duplizieren.

Rückgabewert

Typ
DocumentFragment
Beschreibung
Ein neues DocumentFragment mit tiefen Kopien der Knoten im Bereich. Ist der Bereich zusammengefallen (collapsed), ist das Fragment leer.

Beispiele

Benutzerauswahl als HTML-String auslesen

const getSelectionHtml = () => {
  const selection = window.getSelection();
  if (!selection || selection.rangeCount === 0) return '';

  const fragment = selection.getRangeAt(0).cloneContents();
  const wrapper = document.createElement('div');
  wrapper.append(fragment);
  return wrapper.innerHTML;
};

document.addEventListener('mouseup', () => {
  console.log(getSelectionHtml());
});
z. B. "Hallo <strong>Welt</strong>"

Teilweise ausgewählte Elemente werden mitgeklont

document.body.innerHTML = '<p id="p">Eins <b>Zwei Drei</b> Vier</p>';

const p = document.getElementById('p');
const range = document.createRange();
// Start: im Text "Eins " nach Zeichen 2
range.setStart(p.firstChild, 2);
// Ende: im Text "Zwei Drei" nach Zeichen 4
range.setEnd(p.querySelector('b').firstChild, 4);

const div = document.createElement('div');
div.append(range.cloneContents());
console.log(div.innerHTML);
console.log(p.innerHTML); // Original unverändert
ns <b>Zwei</b> Eins <b>Zwei Drei</b> Vier

Abschnitt eines Dokuments in eine Vorschau kopieren

const source = document.querySelector('article');
const preview = document.querySelector('#preview');

const range = document.createRange();
range.selectNodeContents(source);

const copy = range.cloneContents();
// IDs entfernen, damit keine Duplikate im Dokument entstehen
copy.querySelectorAll('[id]').forEach((el) => el.removeAttribute('id'));

preview.replaceChildren(copy);

// Wichtig · Fallstricke

  • Event-Listener werden nicht kopiert: Listener, die mit addEventListener registriert wurden, fehlen in den Klonen, ebenso Formularzustände, die nicht in Attributen stehen (z. B. der aktuelle value eines Eingabefelds).
  • Doppelte IDs: Die Klone behalten ihre id-Attribute. Wer das Fragment wieder ins Dokument einfügt, sollte sie entfernen oder ändern.
  • DocumentType-Knoten: Liegt ein DocumentType-Knoten im Bereich, wird ein HierarchyRequestError ausgelöst.
  • Sicherheit: Stammt der Inhalt aus nicht vertrauenswürdigen Quellen und wird später über innerHTML weiterverarbeitet, besteht XSS-Gefahr. Die HTML-Ausgabe muss dann bereinigt werden (z. B. mit DOMPurify).
  • <script>-Elemente im Fragment werden beim erneuten Einfügen nicht noch einmal ausgeführt, wenn sie bereits gelaufen sind.
  • Die Methode wird von allen modernen Browsern unterstützt. StaticRange bietet sie nicht an.