องค์ประกอบ DOM ลบ JavaScript


198

ฉันพยายามทดสอบว่ามีองค์ประกอบ DOM อยู่หรือไม่และหากมีอยู่ให้ลบออกและหากไม่มีอยู่ให้สร้างขึ้นมา

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

การตรวจสอบว่ามีอยู่หรือไม่การสร้างองค์ประกอบใช้งานได้ แต่การลบองค์ประกอบไม่ได้ โดยพื้นฐานแล้วโค้ดทั้งหมดนี้จะแทรก iframe ลงในหน้าเว็บโดยคลิกที่ปุ่ม สิ่งที่ฉันต้องการจะเกิดขึ้นคือถ้า iframe อยู่ที่นั่นแล้วเพื่อลบมัน แต่ด้วยเหตุผลบางอย่างฉันล้มเหลว


อาจเป็นไปได้ซ้ำกับJavaScript: ลบองค์ประกอบตาม id
Zaz

คำตอบ:


339

removeChild ควรถูกเรียกใช้บน parent เช่น:

parent.removeChild(child);

ในตัวอย่างของคุณคุณควรทำสิ่งที่ชอบ:

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

ขอบคุณที่คิดออกก่อนที่ฉันจะอ่านโพสต์ของคุณ ต้องเปลี่ยนเป็น whereto.removeChild (whereto.childNodes [0]);
Joshua Redfield

6
สิ่งนี้จะทำงานได้โดยสมมติว่าเฟรมของคุณเป็นลูกคนแรกของdebugdiv เสมอ การใช้parentNodeเป็นโซลูชันทั่วไปที่จะทำงานกับองค์ประกอบใด ๆ
casablanca

1
วิธีนี้อาจไม่เพียงพอ หากใครอ่านข้อความนี้โปรดดูคำแนะนำของ Glenn
Sebas

79

ในเบราว์เซอร์ส่วนใหญ่จะมีวิธีการลบองค์ประกอบจาก DOM ค่อนข้างสั้นกว่าการโทรหาพาเรน.removeChild(element)ต์ซึ่งเป็นการโทรelement.remove()ผู้ปกครองของตนซึ่งเป็นเพียงการโทรในหลักสูตรเนื่องจากนี่อาจเป็นวิธีมาตรฐานและเป็นสำนวนในการลบองค์ประกอบออกจาก DOM

.remove()วิธีการเพิ่มมาตรฐาน DOM ใช้ชีวิตในปี 2011 ( กระทำ ) และได้รับการดำเนินการโดย Chrome, Firefox, Safari, Opera และขอบ ไม่รองรับ Internet Explorer ทุกรุ่น

หากคุณต้องการสนับสนุนเบราว์เซอร์รุ่นเก่าคุณจะต้องใช้มัน สิ่งนี้กลายเป็นเรื่องน่ารำคาญเล็กน้อยทั้งคู่เพราะดูเหมือนว่าไม่มีใครทำ DOM shim อเนกประสงค์ที่มีวิธีการเหล่านี้และเพราะเราไม่เพียงแค่เพิ่มวิธีการในต้นแบบเดียว มันเป็นวิธีการChildNodeซึ่งเป็นเพียงส่วนต่อประสานที่กำหนดโดยข้อกำหนดและไม่สามารถเข้าถึง JavaScript ได้ดังนั้นเราจึงไม่สามารถเพิ่มอะไรลงในต้นแบบได้ ดังนั้นเราจำเป็นต้องค้นหาต้นแบบทั้งหมดที่สืบทอดมาChildNodeและถูกกำหนดในเบราว์เซอร์และเพิ่มลง.removeไป

นี่คือ shim ฉันมาด้วยซึ่งฉันได้ยืนยันงานใน 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;
        }
    }
})();

นี้จะไม่ทำงานใน IE 7 หรือลดลงเนื่องจากการขยายต้นแบบ DOM เป็นไปไม่ได้ก่อนที่ IE 8 ผมคิดว่าในช่วงใกล้จะถึงปี 2558 คนส่วนใหญ่ไม่จำเป็นต้องสนใจเรื่องนี้

เมื่อคุณรวมชิมแล้วคุณจะสามารถลบองค์ประกอบ DOM elementออกจาก DOM ได้ง่ายๆโดยการโทร

element.remove();

1
เพิ่งออกจากที่นี่: polyfill.io/v2/docs/features/#Element_prototype_removeหากคุณรวมบริการ polyfill อัตโนมัติที่คุณจะได้รับการสนับสนุนกลับไปที่ IE 7
มาตรฐาน

4
นี่เป็นวิธีที่ทำได้ในปี 2560 ตราบใดที่คุณไม่สนใจเกี่ยวกับ IE ดู: developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove
nevf

45

ดูเหมือนว่าฉันมีตัวแทนไม่เพียงพอที่จะโพสต์ความคิดเห็นดังนั้นคำตอบอื่นจะต้องทำ

เมื่อคุณยกเลิกการเชื่อมโยงโหนดโดยใช้ removeChild () หรือโดยการตั้งค่าคุณสมบัติ innerHTML บนพาเรนต์คุณต้องตรวจสอบให้แน่ใจว่าไม่มีสิ่งใดที่อ้างอิงถึงมิฉะนั้นจะไม่ถูกทำลายจริง ๆ และจะทำให้หน่วยความจำรั่วไหล มีหลายวิธีที่คุณสามารถทำการอ้างอิงไปยังโหนดก่อนที่จะเรียก removeChild () และคุณต้องตรวจสอบให้แน่ใจว่าการอ้างอิงเหล่านั้นที่ไม่ได้อยู่นอกขอบเขตจะถูกลบออกอย่างชัดเจน

Doug Crockford เขียนที่นี่ว่าตัวจัดการเหตุการณ์เป็นสาเหตุของการอ้างอิงแบบวงกลมใน IE และแนะนำให้ลบอย่างชัดเจนดังต่อไปนี้ก่อนที่จะเรียก 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]);
        }
    }
}

และแม้ว่าคุณจะใช้ความระมัดระวังเป็นจำนวนมากคุณยังสามารถรับหน่วยความจำรั่วใน IE ตามที่ Jens-Ingo Farley อธิบายไว้ที่นี่ที่นี่

และสุดท้ายอย่าตกหลุมพรางของความคิดที่ว่า Javascript deleteเป็นคำตอบ ดูเหมือนว่าหลายคนจะได้รับการแนะนำ แต่จะไม่ทำงาน นี่คือข้อมูลอ้างอิงที่ดีเกี่ยวกับความเข้าใจในการลบโดย Kangax


1
บางทีคุณสามารถแสดง jsFiddle เพื่อพิสูจน์สิ่งนี้ ขอบคุณ
Muhaimin

1
ฉันยืนยันพฤติกรรมนี้ เฟรมเวิร์กของฉันใช้แผนผังการแม็พอ็อบเจ็กต์ Javascript บนโครงร่าง dom แต่ละวัตถุ js อ้างอิงองค์ประกอบ dom ของมัน แม้ว่าฉันelement.parentNode.removeChildจะเรียกให้ลบองค์ประกอบพวกมันยังมีชีวิตอยู่และยังสามารถอ้างอิงได้ พวกเขาไม่สามารถมองเห็นได้ในต้นไม้ปกติ
Sebas

ใช่แล้วลบตัวชี้โกลบอลไปยังวัตถุการแม็พ js ปลดล็อกตัวรวบรวมขยะอย่างน่าอัศจรรย์ นี่เป็นส่วนเสริมที่สำคัญสำหรับคำตอบที่ได้รับการยอมรับ
Sebas

11

การใช้Node.removeChild ()ทำงานให้คุณเพียงใช้สิ่งนี้:

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

ใน DOM 4 มีการใช้วิธีลบ แต่มีการสนับสนุนเบราว์เซอร์ที่ไม่ดีตาม W3C:

วิธีการ node.remove () ถูกนำมาใช้ในสเปค DOM 4 แต่เนื่องจากการสนับสนุนเบราว์เซอร์ไม่ดีคุณจึงไม่ควรใช้

แต่คุณสามารถใช้วิธีการลบถ้าคุณใช้ jQuery ...

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

นอกจากนี้ในเฟรมเวิร์กใหม่เช่นคุณสามารถใช้เงื่อนไขเพื่อลบองค์ประกอบตัวอย่างเช่น*ngIfในเชิงมุมและในการตอบสนองการแสดงผลมุมมองที่แตกต่างกันขึ้นอยู่กับเงื่อนไข ...


1
หากคุณกำลังสร้างโหนดโมดัลใน js โดยใช้ createElement ให้ตรวจสอบว่ามีโหนดอยู่ก่อนที่จะลบหรือไม่ if (leftSection) {.. รหัสของคุณ}ควรทำงาน
Afsan Abdulali Gujarati

0

หากคุณมีความสุขที่จะใช้ฟังก์ชั่นที่ยอดเยี่ยม:

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

หากต้องการลบองค์ประกอบทั้งหมดออกจาก DOM

หากต้องการลบองค์ประกอบโดยไม่ลบข้อมูลและเหตุการณ์ให้ใช้สิ่งนี้แทน:

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

เอกสาร jQuery

.remove()วิธีการใช้เวลาองค์ประกอบจาก DOM ใช้.remove()เมื่อคุณต้องการลบองค์ประกอบเองรวมถึงทุกสิ่งที่อยู่ภายใน นอกเหนือจากองค์ประกอบเองเหตุการณ์ที่ถูกผูกไว้ทั้งหมดและข้อมูล jQuery ที่เกี่ยวข้องกับองค์ประกอบจะถูกลบออก หากต้องการลบองค์ประกอบโดยไม่ลบข้อมูลและเหตุการณ์ให้ใช้.detach()แทน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.