JavaScript DOM menghapus elemen

198

Saya mencoba menguji apakah ada elemen DOM, dan jika memang ada, hapus, dan jika tidak ada, buatlah.

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

Memeriksa apakah ada berfungsi, membuat elemen berfungsi, tetapi menghapus elemen tidak. Pada dasarnya semua kode ini dilakukan adalah menyuntikkan iframe ke halaman web dengan mengklik tombol. Yang ingin saya lakukan adalah jika iframe sudah ada di sana untuk menghapusnya. Tetapi untuk beberapa alasan saya gagal.

Joshua Redfield
sumber
kemungkinan rangkap dari JavaScript: hapus elemen dengan id
Zaz

Jawaban:

338

removeChild harus dipanggil pada orang tua, yaitu:

parent.removeChild(child);

Dalam contoh Anda, Anda harus melakukan sesuatu seperti:

if (frameid) {
    frameid.parentNode.removeChild(frameid);
}
casablanca
sumber
Terima kasih mengetahuinya tepat sebelum saya membaca posting Anda. Harus mengubahnya ke whereto.removeChild (whereto.childNodes [0]);
Joshua Redfield
6
Itu juga akan bekerja dengan asumsi bahwa frame Anda selalu merupakan anak pertama dari debugdiv tersebut. Menggunakan parentNodeadalah solusi yang lebih umum yang akan bekerja dengan elemen apa pun.
casablanca
1
Solusi ini mungkin tidak cukup. Jika ada yang membaca ini, lihat saran Glenn
Sebas
79

Di sebagian besar browser, ada cara yang sedikit lebih ringkas untuk menghapus suatu elemen dari DOM daripada memanggil .removeChild(element)induknya, yaitu dengan hanya menelepon element.remove(). Pada waktunya, ini mungkin akan menjadi cara standar dan idiomatis untuk menghapus elemen dari DOM.

The .remove()Metode ditambahkan ke Living Standard DOM pada tahun 2011 ( komit ), dan sejak itu telah dilaksanakan oleh Chrome, Firefox, Safari, Opera, dan Edge. Itu tidak didukung di versi Internet Explorer apa pun.

Jika Anda ingin mendukung browser yang lebih lama, Anda harus melakukannya. Ini ternyata sedikit menjengkelkan, baik karena sepertinya tidak ada yang membuat shim DOM serba guna yang berisi metode ini, dan karena kita tidak hanya menambahkan metode ke prototipe tunggal; ini adalah metode ChildNode, yang hanya antarmuka yang ditentukan oleh spesifikasi dan tidak dapat diakses oleh JavaScript, jadi kami tidak dapat menambahkan apa pun ke prototipe. Jadi kita perlu menemukan semua prototipe yang mewarisi ChildNodedan sebenarnya didefinisikan di browser, dan menambahkannya .remove.

Inilah shim saya datang dengan, yang saya sudah konfirmasi bekerja di 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;
        }
    }
})();

Ini tidak akan berfungsi di IE 7 atau lebih rendah, karena memperluas prototipe DOM tidak mungkin sebelum IE 8 . Saya pikir, pada ambang tahun 2015 kebanyakan orang tidak perlu peduli tentang hal-hal seperti itu.

Setelah Anda memasukkannya, Anda dapat menghapus elemen DOM elementdari DOM hanya dengan menelepon

element.remove();
Mark Amery
sumber
1
Hanya meninggalkan ini di sini: polyfill.io/v2/docs/features/#Element_prototype_remove jika Anda memasukkan layanan polyfill automagic Anda akan mendapatkan dukungan kembali ke IE 7.
complistic
4
Ini jelas merupakan cara untuk melakukannya pada tahun 2017 selama Anda tidak peduli tentang IE. Lihat: developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove
nevf
45

Sepertinya saya tidak punya cukup perwakilan untuk mengirim komentar, jadi jawaban lain harus dilakukan.

Saat Anda memutuskan tautan sebuah simpul menggunakan removeChild () atau dengan menyetel properti innerHTML pada induknya, Anda juga perlu memastikan bahwa tidak ada yang lain yang merujuknya jika tidak maka sebenarnya tidak akan hancur dan akan menyebabkan kebocoran memori. Ada banyak cara di mana Anda bisa mengambil referensi ke node sebelum memanggil removeChild () dan Anda harus memastikan bahwa referensi yang belum keluar dari ruang lingkup secara eksplisit dihapus.

Doug Crockford menulis di sini bahwa event handler dikenal sebagai penyebab referensi melingkar di IE dan menyarankan untuk menghapusnya secara eksplisit sebagai berikut sebelum memanggil 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]);
        }
    }
}

Dan bahkan jika Anda mengambil banyak tindakan pencegahan Anda masih bisa mendapatkan kebocoran memori di IE seperti yang dijelaskan oleh Jens-Ingo Farley di sini .

Dan akhirnya, jangan jatuh ke dalam perangkap berpikir bahwa menghapus Javascript adalah jawabannya. Tampaknya disarankan oleh banyak orang, tetapi tidak akan melakukan pekerjaan. Berikut ini adalah referensi bagus untuk memahami penghapusan oleh Kangax.

Glenn Lawrence
sumber
1
mungkin Anda bisa menunjukkan beberapa jsFiddle untuk membuktikan ini. Terima kasih
Muhaimin
1
Saya mengkonfirmasi perilaku ini. Kerangka kerja saya menggunakan pohon pemetaan objek Javascript di atas tata letak dom. Setiap objek js mereferensikan elemen domnya. Meskipun saya menelepon element.parentNode.removeChilduntuk menghapus elemen, mereka tetap hidup dan masih bisa direferensikan. Mereka hanya tidak terlihat di pohon dom biasa.
Sebas
Ya, dan kemudian menghapus pointer global ke objek pemetaan js secara ajaib membuka pengumpul sampah. Ini merupakan tambahan penting untuk jawaban yang diterima.
Sebas
11

Menggunakan Node.removeChild () melakukan pekerjaan untuk Anda, cukup gunakan sesuatu seperti ini:

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

Di DOM 4, metode hapus diterapkan, tetapi ada dukungan browser yang buruk menurut W3C:

Metode node.remove () diimplementasikan dalam spesifikasi DOM 4. Tetapi karena dukungan browser yang buruk, Anda tidak boleh menggunakannya.

Tetapi Anda dapat menggunakan metode hapus jika Anda menggunakan jQuery ...

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

Juga dalam kerangka kerja baru seperti Anda dapat menggunakan kondisi untuk menghapus elemen, misalnya *ngIfdalam Angular dan dalam Bereaksi, memberikan tampilan yang berbeda, tergantung pada kondisi ...

Alireza
sumber
1
Jika Anda membuat simpul modal dalam js menggunakan createElement, maka pastikan untuk memeriksa apakah simpul tersebut ada sebelum menghapusnya. jika (bagian kiri) {..kode Anda} harus melakukan pekerjaan.
Afsan Abdulali Gujarati
0

Jika Anda senang menggunakan fungsi brilian:

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

Untuk sepenuhnya menghapus elemen dari DOM.

Untuk menghapus elemen tanpa menghapus data dan acara, gunakan ini sebagai gantinya:

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

jQuery Docs

The .remove()Metode mengambil elemen dari DOM. Gunakan .remove()saat Anda ingin menghapus elemen itu sendiri, serta semua yang ada di dalamnya. Selain elemen itu sendiri, semua acara terikat dan data jQuery terkait dengan elemen dihapus. Untuk menghapus elemen tanpa menghapus data dan acara, gunakan .detach()sebaliknya.

Arya Beezadhur
sumber