HaftungsausschlussEs scheint, als würde ich eine neue Artikelserie starten - ein wenig langweilig und rein zweckmäßig. Sie erklären die Punkte, die meinen Schülern oft Schwierigkeiten bereiten. Wenn Sie ein erfahrener Webentwickler sind, werden Sie höchstwahrscheinlich nicht interessiert sein. Wenn Sie auf Perversionen in der Macht von JS am Freitag warten, werden sie leider nicht hier sein.
Eines der Dinge, die Schüler regelmäßig nicht verstehen können, ist DocumentFragment. Im Allgemeinen kann ich ihnen keine Vorwürfe machen. Mit äußerer Einfachheit hat es mehrere nicht offensichtliche und sogar nicht intuitive Eigenschaften. In diesem Artikel möchte ich alles sammeln, was ein Anfänger über ihn wissen muss.

Was ist das
Ein DocumentFragment ist ein Container, der eine beliebige Anzahl von DOM-Elementen enthalten kann. Wenn ganz einfach, können Sie es sich als einen Eimer vorstellen. Darin sind Elemente gestapelt, so dass sie im richtigen Moment sofort entsorgt werden können.
Wie erstelle ich?
Grundstufe.
var fragment = document.createDocumentFragment();
Es gibt auch andere Möglichkeiten, aber darüber unten.
Warum brauche ich
Wie ich oben geschrieben habe, um DOM-Elemente zu speichern. "Aber sie können in einer gewöhnlichen Diva gespeichert werden", kann der Leser Einwände erheben. Das Fragment hat jedoch eine einzigartige Eigenschaft, die es zum besten Kandidaten für diese Rolle macht. Betrachten Sie den folgenden Code:
var fragment = document.createDocumentFragment(); var parentDiv = document.createElement("div"); var div1 = document.createElement("div"); var div2 = document.createElement("div"); fragment.appendChild(div1); fragment.appendChild(div2);
Was sagt uns die Konsole? Eine Person, die mit DocumentFragment nicht vertraut ist, könnte denken, dass
parentDiv
ein
parentDiv
fragment
. Tatsächlich wird es aber zwei Kinder haben -
div1
und
div2
. Tatsache ist, dass das Fragment selbst kein DOM-Element ist, sondern nur ein Container für DOM-Elemente. Und wenn es als Argument an Methoden wie
appendChild
oder
insertBefore
, wird es nicht in den DOM-Baum eingebettet, sondern bettet dort seinen Inhalt ein.
Aber warum brauchst du es?
Die Eigenschaft "Eimer" ist natürlich gut, aber wie ist dies in der Praxis nützlich? DocumentFragment hat zwei Hauptanwendungsbereiche.
1. Speichern von HTML-Teilen, die keinen gemeinsamen Vorfahren haben.Es gibt Situationen, in denen wir den Inhalt eines Elements ersetzen müssen, aber das Element selbst nicht berühren müssen. Angenommen, wir verwenden die Ereignisdelegierung und alle Ereignishandler, die für interne Elemente auftreten, werden an ein externes Div gehängt. In diesem Fall ist DocumentFragment ideal für uns:
div.innerHTML = ""; div.appendChild(fragmentWithAllContent);
"Aber können wir dem div sofort Elemente hinzufügen, wenn wir sie erstellen?" - Der ätzende Leser wird fragen. Wir können, aber es lohnt sich nicht, und deshalb.
2. Leistungsverbesserung bei mehreren Einsätzen.Tatsache ist, dass der Browser jedes Mal, wenn wir etwas im aktiven DOM-Baum ändern, eine Reihe von Berechnungen durchführen muss. Hier können Sie zum Beispiel mehr darüber lesen. In diesem Artikel beschränken wir uns darauf zu erwähnen, dass es so einen schrecklichen Biest-Reflow gibt. Wenn wir der Seite ein Element hinzufügen, wacht dieses Biest auf und frisst ein Stück Prozessorzeit. Wenn wir nacheinander einhundert Elemente hinzufügen, wacht das Tier hundertmal auf und beißt hundertmal. Für den Benutzer kann dies bereits ein merkliches „Einfrieren“ sein.
Wenn wir dem DocumentFragment ein Element hinzufügen, führt dies nicht zu einem Reflow, da das Fragment nicht Teil des aktiven DOM-Baums ist (und im Grunde nicht sein kann). Und vor allem: Wenn wir den Inhalt eines Fragments mit
appendChild
oder anderen ähnlichen Methoden einfügen, wird der
Reflow nur einmal aufgerufen , unabhängig davon, wie viele Elemente sich im Fragment befinden.
Aus Gründen der Klarheit habe ich einen
einfachen Benchmark erstellt, damit der Leser den Unterschied persönlich erkennen kann.
Upd: Genosse Nuit
sagte, dass meine Worte für modernes Chrome nicht mehr wahr sind. Der Reflow wird nicht früher als nötig ausgeführt, und dank dessen funktioniert der Code ohne DocumentFragment tatsächlich
schneller , und bei anderen Browsern ist dies nicht so offensichtlich. Bevor Sie sich für die Verwendung von Fragmenten entscheiden, müssen Sie ein Profil erstellen und die Zielgruppe der Website untersuchen.
Nuancen
Es gibt zwei Funktionen, die es Anfängern oft schwer machen, Fragmente zu verwenden. Erstens: Wie ich oben geschrieben habe, ist ein Fragment
kein DOM-Element . Dies bedeutet, dass es viele bekannte Methoden und Eigenschaften fehlt, insbesondere
innerHTML
. Daher können Sie eine Zeichenfolge nicht einfach in den Inhalt eines Fragments umwandeln. Wie das geht, ist nicht einfach, wird weiter unten beschrieben.
Das zweite Merkmal: das Fragment bei Verwendung von "Beute". Genauer gesagt wird es geleert. Wenn wir
div.appendChild(fragment)
, werden alle
div.appendChild(fragment)
des Fragments in ein
div
. Und da ein Element nicht mehr als ein übergeordnetes Element haben kann, bedeutet dies, dass sie aus dem Fragment entfernt werden! Um dieses Verhalten zu vermeiden, wenn es unerwünscht ist, können Sie
cloneNode
.
<template> -Tag
Es gibt einen Ort, an dem Sie auf DocumentFragment stoßen können, ohne es über JS zu erstellen. Dies ist die
content
des Vorlagenelements.
Das
<template>
speziell zum Speichern von HTML-Codeteilen entwickelt, jedoch nicht zum Laden des Browsers im Voraus. Was sich in diesem Tag befindet, wird nicht Teil des aktiven DOM-Baums. Insbesondere (Neulinge stoßen häufig auch darauf) können sie mit
querySelector
nicht gefunden werden. Aus HTML-Code im
<template>
-Tag erstellte Elemente werden nicht zu untergeordneten Elementen. Stattdessen kann JavaScript über die Eigenschaft
content
auf sie zugreifen, was eine Überraschung ist! - nur DocumentFragment.
Mit dem Vorlagenelement können Sie ein Fragment aus einer Zeichenfolge erstellen:
function createFragmentFromString(str){ var template = document.createElement("template"); template.innerHTML = str; return template.content; }
Nachwort
Wenn Sie neu in der Webentwicklung sind, hoffe ich, dass Sie viel gelernt haben. Wenn Sie ein erfahrener Entwickler sind, möchten Sie diesen Artikel möglicherweise durch etwas ergänzen. In diesem Fall zögern Sie nicht, in den Kommentaren darüber zu schreiben. Danke fürs Lesen und einen schönen Tag.