JavaScript DOM kaldırma öğesi


198

Bir DOM öğesinin olup olmadığını test etmeye çalışıyorum ve eğer varsa onu silin ve yoksa onu oluşturun.

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

Var olup olmadığını kontrol etmek, öğeyi oluşturmak çalışır, ancak öğeyi silmek işe yaramaz. Temel olarak bu kodun yaptığı tek şey bir düğmeye tıklayarak bir web sayfasına iframe enjekte etmektir. Olmak istediğim iframe zaten silmek için oradaysa. Ama nedense başarısız oluyorum.


olası JavaScript
Zaz

Yanıtlar:


339

removeChild ebeveyn üzerinde çağrılmalıdır, yani:

parent.removeChild(child);

Örneğinizde, şöyle bir şey yapmalısınız:

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

Teşekkürler yazınızı okumadan hemen önce anladım. Whereto.removeChild (whereto.childNodes [0]) olarak değiştirmek zorunda kaldım;
Joshua Redfield

6
Bu, çerçevenizin her zaman debugdiv'in ilk çocuğu olduğunu varsayarsak da işe yarar. Kullanmak parentNode, herhangi bir öğeyle çalışacak daha genel bir çözümdür.
casablanca

1
Bu çözüm yeterli olmayabilir. Herkes bunu okuyorsa lütfen Glenn'in önerisine bir göz atın
Sebas

79

Çoğu tarayıcıda çağırmaktan daha DOM unsurunu kaldırma biraz daha kısa ve öz yolu var .removeChild(element)sadece çağrısına ise, ailesindeki üzerinde element.remove(). Zamanla, bu muhtemelen bir öğeyi DOM'dan kaldırmanın standart ve deyimsel yolu haline gelecektir.

.remove()Yöntem 2011 yılında DOM Yaşam Standardı (eklendi işlemek ), ve o zamandan beri Chrome, Firefox, Safari, Opera ve Kenar tarafından uygulamaya konmuştur. Internet Explorer'ın hiçbir sürümünde desteklenmemiştir.

Eski tarayıcıları desteklemek istiyorsanız, tarayıcıyı takmanız gerekir. Bu biraz rahatsız edici görünüyor, çünkü kimse bu yöntemleri içeren çok amaçlı bir DOM şim yapmamış gibi görünüyor ve çünkü yöntemi sadece tek bir prototipe eklemiyoruz; ChildNodeyalnızca spec tarafından tanımlanan ve JavaScript tarafından erişilemeyen bir arayüz olan bir yöntemdir , bu nedenle prototipine hiçbir şey ekleyemeyiz. Bu nedenle ChildNode, tarayıcıdan devralınan ve aslında tanımlanmış olan tüm prototipleri bulmamız ve bunlara eklememiz .removegerekir.

IE 8'de çalıştığını onayladığım şim.

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

IE 7'den önce DOM prototiplerini genişletmek mümkün olmadığından , bu IE 7 veya daha düşük sürümlerde çalışmaz . Bununla birlikte, 2015'in eşiğinde çoğu insanın böyle şeyleri önemsememesi gerektiğini anlıyorum.

Onları ekledikten sonra, elementsadece arayarak bir DOM öğesini DOM'dan kaldırabilirsiniz

element.remove();


4
IE ile ilgilenmediğiniz sürece bu kesinlikle 2017'de bunu yapmanın yoludur. Bakınız: developer.mozilla.org/tr-TR/docs/Web/API/ChildNode/remove
nevf

45

Yorum göndermek için yeterli temsilcim yok gibi görünüyor, bu yüzden başka bir cevap yapmak zorunda kalacak.

RemoveChild () kullanarak veya üst öğe üzerinde innerHTML özelliğini ayarlayarak bir düğümün bağlantısını kaldırdığınızda, başka bir öğeye başvuruda bulunmadığından emin olmanız gerekir, aksi takdirde gerçekten yok edilmez ve bellek sızıntısına neden olur. RemoveChild () öğesini çağırmadan önce düğüme başvuruda bulunabileceğiniz birçok yol vardır ve kapsam dışına çıkmamış olan referansların açıkça kaldırıldığından emin olmanız gerekir.

Doug Crockford yazıyor burada ) (olay işleyicileri IE dairesel referansların nedenini bilinmektedir ve removeChild çağırmadan önce olduğu gibi açıkça bunları kaldırmayı takip önerir olduğunu

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

Ve çok fazla önlem alsanız bile, burada Jens-Ingo Farley tarafından tarif edildiği gibi IE'de bellek sızıntıları alabilirsiniz .

Ve son olarak, Javascript'i silmenin cevap olduğunu düşünme tuzağına düşmeyin . Birçok kişi tarafından öneriliyor gibi görünüyor, ancak işi yapmayacak. İşte anlamaya büyük bir referanstır silme Kangax tarafından.


1
belki bunu kanıtlamak için bazı jsFiddle gösterebilirsiniz. Thanks
Muhaimin

1
Bu davranışı onaylıyorum. Benim çerçevem ​​dom düzeni üzerinde bir Javascript nesne eşleme ağacı kullanır. Her js nesnesi dom öğesine başvurur. element.parentNode.removeChildÖğeleri kaldırmak için aramama rağmen , onlar hayatta kalır ve yine de başvurulabilir. Normal dom ağacında görünmezler.
Sebas

Evet ve sonra o js eşleme nesnesine genel işaretçiyi kaldırmak sihirli bir şekilde çöp toplayıcı kilidini açar. Bu, kabul edilen cevaba önemli bir ektir.
Sebas

11

Node.removeChild () yöntemini kullanarak işi sizin yerinize yapabilirsiniz;

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

DOM 4'te, kaldırma yöntemi uygulandı, ancak W3C'ye göre zayıf bir tarayıcı desteği var:

Node.remove () yöntemi DOM 4 belirtiminde uygulanır. Ancak zayıf tarayıcı desteği nedeniyle kullanmamalısınız.

Ancak jQuery kullanıyorsanız remove yöntemini kullanabilirsiniz ...

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

Ayrıca sizin gibi yeni çerçevelerde, bir öğeyi kaldırmak için koşulları kullanabilirsiniz, örneğin *ngIfAçısal ve Tepki'de, farklı görünümler oluşturmak koşullara bağlıdır ...


1
JE'de createElement kullanarak kalıcı düğüm oluşturuyorsanız, düğümü kaldırmadan önce var olup olmadığını kontrol ettiğinizden emin olun. if (leftSection) {..kodunuz} işi yapmalıdır.
Afsan Abdulali Gujarati

0

Parlak işlevi kullanmaktan memnunsanız:

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

Öğeyi DOM'den tamamen silmek için.

Verileri ve olayları kaldırmadan öğeleri kaldırmak için bunun yerine şunu kullanın:

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

jQuery Belgeleri

.remove()Yöntem DOM üzerinden elemanları alır. .remove()Öğenin kendisini ve içindeki her şeyi kaldırmak istediğinizde kullanın . Öğelerin kendilerine ek olarak, öğelerle ilişkili tüm ilişkili olaylar ve jQuery verileri kaldırılır. Verileri ve olayları kaldırmadan öğeleri kaldırmak için .detach()kullanın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.