jQuery / Methode / .detach() - Elemente entfernen und für die Wiederverwendung behalten
jQuerys .detach() entfernt ausgewählte Elemente aus dem Document Object Model (DOM), behält aber ihre zugehörigen jQuery-Daten und Ereignisse. Speichern Sie das zurückgegebene jQuery-Objekt oder eine vorhandene Referenz in einer Variablen, um sie später wieder einzufügen. Das ist keine dauerhafte Speicherung im Browser oder auf einem Server.
Zwischen detach, remove und empty wählen
.detach() eignet sich für Elemente, die vorübergehend aus dem Dokument genommen und wiederverwendet werden. Element und Kinder werden gemeinsam getrennt; mit einer Referenz können Sie dieselben Knoten zurücksetzen. Anders als beim Verbergen mit CSS befinden sie sich nicht mehr im Dokument und werden durch eine neue Dokumentsuche nicht gefunden.
| Methode | Was wird aus dem Dokument entfernt? | jQuery-Daten/Ereignisse entfernter Teile | Typischer Zweck |
|---|---|---|---|
| .detach() | Ausgewählte Elemente samt Inhalt | Bleiben erhalten | Vorübergehend entfernen und wiederverwenden |
| .remove() | Ausgewählte Elemente samt Inhalt | Werden bereinigt | Elemente verwerfen |
| .empty() | Kinder und Text ausgewählter Elemente | Bei entfernten Kindern bereinigt | Behälter behalten, Inhalt leeren |
.remove() zerstört ein von einer JavaScript-Variablen referenziertes Knotenobjekt nicht zwangsläufig sofort. Erneutes Einfügen stellt bereinigte jQuery-Daten und Ereignisse jedoch nicht automatisch wieder her. .empty() lässt den Behälter selbst bestehen. Entscheiden Sie daher nicht nur nach dem gleichen sichtbaren Verschwinden.
Vollständiges Beispiel mit Eingabewert und Ereignis
Speichern Sie den gesamten Code in UTF-8 als detach-demo.html und öffnen Sie ihn im Browser. Zum Laden der offiziellen jQuery-Datei 4.0.0 vom Content Delivery Network (CDN) benötigen Sie Internet, aber keine Paketinstallation. Eingabewert, identischer Knoten, ursprüngliche Position, wiederholtes Trennen/Reset und die Konsolenvergleiche unten wurden mit 3.7.1 und 4.0.0 ausgeführt.
Ein Kommentarknoten vor der Karte markiert ihre Position. Er bleibt beim Trennen stehen, damit Restore die Karte an dieselbe Stelle setzt. Die Karte speichert count mit .data(); ihr untergeordneter Button hat einen direkt gebundenen Ereignishandler.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Detach and restore an editable card</title>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<style>
body { font: 16px/1.6 sans-serif; max-width: 760px; margin: 24px auto; padding: 16px; }
button, input { font: inherit; margin: 4px; max-width: 100%; }
.card { border: 2px solid teal; padding: 16px; margin: 12px 0; }
</style>
</head>
<body>
<h1>Detach and restore a card</h1>
<button type="button" id="detach">Detach</button>
<button type="button" id="restore">Restore</button>
<button type="button" id="reset">Reset</button>
<div id="slot">
<p>Before the card</p>
<p id="after">After the card</p>
</div>
<p id="result" aria-live="polite"></p>
<script>
$(function () {
const anchor = document.createComment("card position");
$("#after").before(anchor);
let $saved = null;
function makeCard() {
const $card = $('<section class="card"><label>Note <input value="Keep me"></label><p>Count: <span class="count">0</span></p><button type="button" class="increment">Increment</button></section>');
$card.data("count", 0);
$card.find(".increment").on("click", function () {
const count = $card.data("count") + 1;
$card.data("count", count).find(".count").text(count);
report();
});
return $card;
}
let $card = makeCard().insertAfter(anchor);
function report() {
const attached = document.contains($card[0]);
$("#result").text(`attached=${attached} | saved=${$saved !== null} | count=${$card.data("count")}`);
}
$("#detach").on("click", function () {
if ($saved !== null) return;
$saved = $card.detach();
report();
});
$("#restore").on("click", function () {
if ($saved === null) return;
$saved.insertAfter(anchor);
$saved = null;
report();
});
$("#reset").on("click", function () {
$card.remove();
$saved = null;
$card = makeCard().insertAfter(anchor);
report();
});
report();
});
</script>
</body>
</html>
Anfangs ist die Karte eingefügt und nicht separat als getrennt gespeichert:
attached=true | saved=false | count=0
- Ändern Sie Note zu Edited note und drücken Sie einmal Increment auf der Karte. Count wird 1.
- Drücken Sie Detach. Die Karte verschwindet; Ergebnis
attached=false | saved=true | count=1. Daten bleiben, eine neue Suche nach .card im Dokument findet jedoch nichts. - Restore setzt die Karte zwischen Before und After zurück. Edited note und Count 1 bleiben.
- Increment erhöht nun auf 2. Auch der Handler des Kindes blieb erhalten.
- Wiederholtes Detach oder Restore verliert oder dupliziert die Karte nicht, weil der Code den Speicherzustand prüft.
- Reset funktioniert auch im getrennten Zustand. Es bereinigt die alte Karte mit .remove() und erstellt eine neue mit Keep me und Count 0.
Den aktuellen Eingabewert desselben Knotens zu behalten unterscheidet sich von neuem HTML als Quelle eines neuen Knotens. Restore fügt den gespeicherten Knoten ein; Reset erzeugt ausdrücklich einen neuen. Jede neue Karte erhält den Handler einmal, sodass Reset keine mehrfachen Aufrufe pro Klick ansammelt.
Daten und Ereignisse mit remove vergleichen
Führen Sie diesen vollständigen Teilcode in der Entwicklerkonsole aus. Er erstellt zwei Buttons in einem temporären Behälter, trennt einen mit detach, entfernt den anderen mit remove und fügt beide wieder ein. Die letzte Zeile bereinigt den Testbehälter.
const $host = $("<div>").appendTo("body");
let keptClicks = 0;
let removedClicks = 0;
const $keep = $("<button>Keep</button>").data("token", "kept")
.on("click", () => keptClicks++).appendTo($host);
const $gone = $("<button>Remove</button>").data("token", "gone")
.on("click", () => removedClicks++).appendTo($host);
const originalNode = $keep[0];
const $saved = $keep.detach();
console.log(`detached=${!document.contains($saved[0])} | data=${$saved.data("token")}`);
$saved.appendTo($host).trigger("click");
const $removed = $gone.remove();
$removed.appendTo($host).trigger("click");
console.log(`same node=${$saved[0] === originalNode} | kept clicks=${keptClicks}`);
console.log(`removed data=${typeof $removed.data("token")} | removed clicks=${removedClicks}`);
$host.remove();
detached=true | data=kept
same node=true | kept clicks=1
removed data=undefined | removed clicks=0
Der getrennte Button ist derselbe Knoten und behält token sowie Handler: kept clicks ist 1. Auch der entfernte Button lässt sich über seine Referenz einfügen, aber seine jQuery-Daten sind undefined und der direkte Handler wurde bereinigt: removed clicks ist 0. Der Vergleich betrifft jQuery-Daten und Ereignisse; externe Timer oder Zustände anderer Bibliotheken werden dadurch nicht pauschal bereinigt.
Selektorfilter und Wiederherstellung beachten
Der Selektor in .detach(selector) filtert die bereits ausgewählte Menge. Er sucht keine neuen Kinder innerhalb dieser Elemente. Im folgenden Konsolenbeispiel werden A und B ausgewählt, aber nur B mit .take getrennt; A bleibt im Behälter. Die letzten zwei Zeilen bereinigen referenzierte Knoten und Testbehälter.
const $list = $('<div><p class="keep">A</p><p class="take">B</p></div>').appendTo("body");
const $items = $list.children("p");
$items.detach(".take");
console.log(`remaining=${$list.children("p").text()}`);
$items.remove();
$list.remove();
remaining=A
Eine neue Suche mit $(".card") findet die getrennte Karte nicht. Verwenden Sie die gespeicherte Referenz und verwalten Sie die alte Position gesondert, etwa mit dem Kommentar. .appendTo() fügt am Zielende ein und merkt sich keine frühere Position. Ein Ziel verschiebt den bestehenden Knoten, mehrere können Kopien erzeugen; prüfen Sie die Zielanzahl.
Ein am Elternteil mit .on() delegiertes Ereignis benötigt Ereignisweitergabe durch diesen Elternteil. Ein verschobenes Element nimmt dessen delegierte Handler nicht mit zu einem anderen Behälter. Das Beispiel bindet den Handler direkt am Kind, um die Erhaltung eindeutig zu zeigen.
Prüfen Sie bei fehlgeschlagener Wiederherstellung, ob die Variable überschrieben wurde und ob Markierung oder Ziel noch im Dokument stehen. Lange gespeicherte Referenzen halten getrennte Objekte erreichbar. Wenn die Wiederverwendung endet, bereinigen Sie jQuery-Zustand mit .remove() und lösen Referenzen. Timer und externe Abonnements beenden Sie über deren eigene APIs.




