JavaScript DOM Element entfernen

198

Ich versuche zu testen, ob ein DOM-Element vorhanden ist. Wenn es vorhanden ist, löschen Sie es und erstellen Sie es, wenn es nicht vorhanden ist.

var duskdawnkey = localStorage["duskdawnkey"];
var iframe = document.createElement("iframe");
var whereto = document.getElementById("debug");
var frameid = document.getElementById("injected_frame");
iframe.setAttribute("id", "injected_frame");
iframe.setAttribute("src", 'http://google.com');
iframe.setAttribute("width", "100%");
iframe.setAttribute("height", "400");

if (frameid) // check and see if iframe is already on page
{ //yes? Remove iframe
    iframe.removeChild(frameid.childNodes[0]);
} else // no? Inject iframe
{
    whereto.appendChild(iframe);
    // add the newly created element and it's content into the DOM
    my_div = document.getElementById("debug");
    document.body.insertBefore(iframe, my_div);
}

Überprüfen, ob es funktioniert, funktioniert, das Element funktioniert, das Löschen des Elements jedoch nicht. Grundsätzlich fügt dieser Code lediglich einen Iframe in eine Webseite ein, indem er auf eine Schaltfläche klickt. Was ich gerne machen würde, ist, wenn der Iframe bereits da ist, um ihn zu löschen. Aber aus irgendeinem Grund versage ich.

Joshua Redfield
quelle
Mögliches Duplikat von JavaScript: Element durch ID entfernen
Zaz

Antworten:

338

removeChild sollte auf dem Elternteil aufgerufen werden, dh:

parent.removeChild(child);

In Ihrem Beispiel sollten Sie Folgendes tun:

if (frameid) {
    frameid.parentNode.removeChild(frameid);
}
casablanca
quelle
Danke, habe es herausgefunden, bevor ich deinen Beitrag gelesen habe. Musste es in whereeto.removeChild (whereeto.childNodes [0]) ändern;
Joshua Redfield
6
Das würde auch funktionieren, wenn Ihr Rahmen immer das erste Kind des debugDiv ist. Die Verwendung parentNodeist eine allgemeinere Lösung, die mit jedem Element funktioniert.
Casablanca
1
Diese Lösung reicht möglicherweise nicht aus. Wenn jemand dies liest, werfen Sie bitte einen Blick auf Glenns Vorschlag
Sebas
79

In den meisten Browsern gibt es eine etwas prägnantere Möglichkeit, ein Element aus dem DOM zu entfernen, als das .removeChild(element)übergeordnete Element aufzurufen , nämlich nur aufzurufen element.remove(). Zu gegebener Zeit wird dies wahrscheinlich die standardmäßige und idiomatische Methode zum Entfernen eines Elements aus dem DOM sein.

Die .remove()Methode wurde 2011 zum DOM Living Standard hinzugefügt ( Commit ) und wurde seitdem von Chrome, Firefox, Safari, Opera und Edge implementiert. Es wurde in keiner Version von Internet Explorer unterstützt.

Wenn Sie ältere Browser unterstützen möchten, müssen Sie diese anpassen. Dies stellt sich als etwas irritierend heraus, sowohl weil anscheinend niemand einen Allzweck-DOM-Shim hergestellt hat, der diese Methoden enthält, als auch weil wir die Methode nicht nur einem einzelnen Prototyp hinzufügen. Es handelt sich um eine Methode von ChildNode, die nur eine durch die Spezifikation definierte Schnittstelle ist und für JavaScript nicht zugänglich ist. Daher können wir dem Prototyp nichts hinzufügen. Wir müssen also alle Prototypen finden, die von ChildNodedem Browser erben und tatsächlich im Browser definiert sind, und sie ergänzen .remove.

Hier ist die Unterlegscheibe, die ich mir ausgedacht habe und von der ich bestätigt habe, dass sie in IE 8 funktioniert.

(function () {
    var typesToPatch = ['DocumentType', 'Element', 'CharacterData'],
        remove = function () {
            // The check here seems pointless, since we're not adding this
            // method to the prototypes of any any elements that CAN be the
            // root of the DOM. However, it's required by spec (see point 1 of
            // https://dom.spec.whatwg.org/#dom-childnode-remove) and would
            // theoretically make a difference if somebody .apply()ed this
            // method to the DOM's root node, so let's roll with it.
            if (this.parentNode != null) {
                this.parentNode.removeChild(this);
            }
        };

    for (var i=0; i<typesToPatch.length; i++) {
        var type = typesToPatch[i];
        if (window[type] && !window[type].prototype.remove) {
            window[type].prototype.remove = remove;
        }
    }
})();

Dies funktioniert in IE 7 oder niedriger nicht, da die Erweiterung von DOM-Prototypen vor IE 8 nicht möglich ist . Ich denke jedoch, dass sich die meisten Menschen am Rande des Jahres 2015 nicht um solche Dinge kümmern müssen.

Sobald Sie sie Shim eingefügt haben, können Sie ein DOM-Element elementdurch einfaches Aufrufen aus dem DOM entfernen

element.remove();
Mark Amery
quelle
1
Lassen Sie dies einfach hier: polyfill.io/v2/docs/features/#Element_prototype_remove Wenn Sie diesen automatischen Polyfill-Service einschließen, erhalten Sie Unterstützung für IE 7.
Complistic
4
Dies ist definitiv der Weg, dies im Jahr 2017 zu tun, solange Sie sich nicht für IE interessieren. Siehe: developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove
nevf
45

Scheint, als hätte ich nicht genug Repräsentanten, um einen Kommentar zu schreiben, also muss eine andere Antwort reichen.

Wenn Sie die Verknüpfung eines Knotens mit removeChild () aufheben oder die innerHTML-Eigenschaft für das übergeordnete Element festlegen, müssen Sie auch sicherstellen, dass nichts anderes darauf verweist, da er sonst nicht zerstört wird und zu einem Speicherverlust führt. Es gibt viele Möglichkeiten, wie Sie vor dem Aufrufen von removeChild () einen Verweis auf den Knoten hätten erstellen können, und Sie müssen sicherstellen, dass die Verweise, die nicht außerhalb des Gültigkeitsbereichs liegen, explizit entfernt werden.

Doug Crockford schreibt hier, dass Ereignishandler als Ursache für Zirkelverweise im IE bekannt sind, und schlägt vor, sie wie folgt explizit zu entfernen, bevor removeChild () aufgerufen wird.

function purge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        for (i = a.length - 1; i >= 0; i -= 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            purge(d.childNodes[i]);
        }
    }
}

Und selbst wenn Sie viele Vorsichtsmaßnahmen treffen, können im IE Speicherlecks auftreten, wie von Jens-Ingo Farley hier beschrieben .

Und schließlich sollten Sie nicht in die Falle tappen, wenn Sie denken, dass das Löschen von Javascript die Antwort ist. Es scheint von vielen vorgeschlagen zu werden, wird aber den Job nicht machen. Hier ist eine gute Referenz zum Verständnis von Löschen durch Kangax.

Glenn Lawrence
quelle
1
Vielleicht können Sie etwas jsFiddle zeigen, um dies zu beweisen. Danke
Muhaimin
1
Ich bestätige dieses Verhalten. Mein Framework verwendet einen Javascript-Objektzuordnungsbaum über dem Dom-Layout. Jedes js-Objekt verweist auf sein dom-Element. Obwohl ich aufrufe element.parentNode.removeChild, um Elemente zu entfernen, bleiben sie am Leben und können trotzdem referenziert werden. Sie sind im regulären Dombaum einfach nicht sichtbar.
Sebas
Ja, und wenn Sie dann den globalen Zeiger auf das js-Zuordnungsobjekt entfernen, wird der Garbage Collector auf magische Weise entsperrt. Dies ist eine wichtige Ergänzung zur akzeptierten Antwort.
Sebas
11

Die Verwendung von Node.removeChild () erledigt den Job für Sie. Verwenden Sie einfach Folgendes :

var leftSection = document.getElementById('left-section');
leftSection.parentNode.removeChild(leftSection);

In DOM 4 wurde die Methode zum Entfernen angewendet, aber laut W3C gibt es eine schlechte Browserunterstützung:

Die Methode node.remove () ist in der DOM 4-Spezifikation implementiert. Aufgrund der schlechten Browserunterstützung sollten Sie diese jedoch nicht verwenden.

Sie können jedoch die Methode remove verwenden, wenn Sie jQuery verwenden ...

$('#left-section').remove(); //using remove method in jQuery

Auch in neuen Frameworks, wie Sie Bedingungen verwenden können, um ein Element zu entfernen, z. B. *ngIfin Angular und in React, hängt das Rendern unterschiedlicher Ansichten von den Bedingungen ab ...

Alireza
quelle
Wenn Sie mit createElement einen modalen Knoten in js erstellen, überprüfen Sie einfach, ob der Knoten vorhanden ist, bevor Sie ihn entfernen. if (leftSection) {..Ihr Code} sollte die Arbeit erledigen.
Afsan Abdulali Gujarati
0

Wenn Sie gerne jQuery verwenden

Verwenden Sie die brillante jQuery-Funktion:

$("#foo").remove();

Um das Element vollständig aus dem DOM zu löschen.

Verwenden Sie stattdessen Folgendes, um die Elemente zu entfernen, ohne Daten und Ereignisse zu entfernen:

$("#foo").detach();

Dokumentreferenz

Die .remove()Methode nimmt Elemente aus dem DOM heraus. Verwenden .remove()Sie diese Option, wenn Sie das Element selbst sowie alle darin enthaltenen Elemente entfernen möchten. Zusätzlich zu den Elementen selbst werden alle gebundenen Ereignisse und jQuery-Daten, die den Elementen zugeordnet sind, entfernt. Verwenden Sie .detach()stattdessen, um die Elemente zu entfernen, ohne Daten und Ereignisse zu entfernen .

Aryan Beezadhur
quelle