web-dev-qa-db-fra.com

JavaScript DOM remove element

J'essaie de tester si un élément DOM existe, et s'il existe, le supprime et s'il n'existe pas, créez-le.

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);
}

Vérifier si cela fonctionne, créer l'élément fonctionne, mais supprimer l'élément ne fonctionne pas. En gros, tout ce code consiste à injecter un iframe dans une page Web en cliquant sur un bouton. Ce que je voudrais, c’est que si l’iframe est déjà là pour le supprimer. Mais pour une raison quelconque, j'échoue.

177
Joshua Redfield

removeChild doit être invoqué sur le parent, c'est-à-dire:

parent.removeChild(child);

Dans votre exemple, vous devriez faire quelque chose comme:

if (frameid) {
    frameid.parentNode.removeChild(frameid);
}
309
casablanca

Dans la plupart des navigateurs, il existe un moyen légèrement plus succinct de supprimer un élément du DOM que d'appeler .removeChild(element) sur son parent, qui consiste simplement à appeler element.remove(). En temps voulu, cela deviendra probablement le moyen standard et idiomatique de supprimer un élément du DOM.

La méthode .remove() a été ajoutée au DOM Living Standard en 2011 ( commit ) et a depuis été implémentée par Chrome, Firefox, Safari, Opera et Edge. Il n'a été pris en charge par aucune version d'Internet Explorer.

Si vous souhaitez prendre en charge des navigateurs plus anciens, vous devrez le caler. Cela s'avère un peu irritant, à la fois parce que personne ne semble avoir créé de shim DOM à usage général contenant ces méthodes et parce que nous ne sommes pas en train de l'ajouter à un seul prototype; c'est une méthode de ChildNode, qui n'est qu'une interface définie par la spécification et n'est pas accessible à JavaScript. Nous ne pouvons donc rien ajouter à son prototype. Nous devons donc rechercher tous les prototypes hérités de ChildNode et définis dans le navigateur, et y ajouter .remove.

Voici la cale que j’ai trouvée, et dont j’ai confirmé le fonctionnement dans IE 8.

(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;
        }
    }
})();

Cela ne fonctionnera pas dans IE 7 ou inférieur, car l'extension de prototypes DOM n'est pas possible avant IE 8 . Je suppose cependant que vers 2015, la plupart des gens n'ont pas à se soucier de ce genre de choses.

Une fois que vous les avez inclus, vous pourrez supprimer un élément DOM element du DOM en appelant simplement

element.remove();
65
Mark Amery

On dirait que je n'ai pas assez de représentant pour poster un commentaire, donc une autre réponse devra être faite.

Lorsque vous dissociez un nœud à l'aide de removeChild () ou en définissant la propriété innerHTML sur le parent, vous devez également vous assurer qu'il n'y a rien d'autre qui le référence car il ne sera pas réellement détruit et entraînera une fuite de mémoire. Vous auriez pu prendre une référence au nœud de nombreuses manières avant d'appeler removeChild () et vous devez vous assurer que les références qui ne sont pas sorties de la portée sont explicitement supprimées.

Doug Crockford écrit ici que les gestionnaires d'événements sont une cause de références circulaires dans IE et suggère de les supprimer explicitement comme suit avant d'appeler removeChild ()

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]);
        }
    }
}

Et même si vous prenez beaucoup de précautions, vous pouvez toujours avoir des fuites de mémoire dans IE comme décrit par Jens-Ingo Farley ici .

Et enfin, ne tombez pas dans le piège consistant à penser que Javascript delete est la solution. Cela semble être suggéré par beaucoup, mais ne fera pas le travail. Ici est une excellente référence pour comprendre supprimer par Kangax.

41
Glenn Lawrence

Utiliser Node.removeChild () fait le travail à votre place, utilisez simplement quelque chose comme ceci:

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

Dans DOM 4, la méthode de suppression était appliquée, mais la prise en charge du navigateur par le W3C est médiocre:

La méthode node.remove () est implémentée dans la spécification DOM 4. Mais en raison de la mauvaise prise en charge du navigateur, vous ne devriez pas l'utiliser.

Mais vous pouvez utiliser la méthode remove si vous utilisez jQuery ...

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

De même, dans les nouveaux frameworks, vous pouvez utiliser des conditions pour supprimer un élément, par exemple *ngIf dans Angular et dans React, le rendu de différentes vues dépend des conditions ...

7
Alireza