जावास्क्रिप्ट डोम तत्व को हटा दें


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 पहले से ही इसे हटाने के लिए है। लेकिन किसी कारण से मैं असफल हो रहा हूं।


जवाबों:


339

removeChild माता-पिता पर आमंत्रित किया जाना चाहिए, अर्थात:

parent.removeChild(child);

आपके उदाहरण में, आपको कुछ ऐसा करना चाहिए:

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

धन्यवाद इससे पहले कि मैं आपकी पोस्ट पढ़ूं, यह सही है। इसे बदलकर whereto.removeChild (whereto.childNodes [0]) करना पड़ा;
जोशुआ रेडफील्ड

6
यह भी यह मानते हुए काम करेगा कि आपका फ्रेम हमेशा debugdiv का पहला बच्चा है । उपयोग करना parentNodeएक अधिक सामान्य समाधान है जो किसी भी तत्व के साथ काम करेगा।
कैसाब्लांका

1
यह समाधान पर्याप्त नहीं हो सकता है। अगर कोई इसे पढ़ रहा है तो कृपया ग्लेन के सुझाव पर एक नज़र डालें
सेबास जूल

79

अधिकांश ब्राउज़रों में, .removeChild(element)अपने माता-पिता को कॉल करने की तुलना में DOM से एक तत्व को हटाने का थोड़ा अधिक संक्षिप्त तरीका है , जिसे सिर्फ कॉल करना है element.remove()। नियत समय में, यह संभवतः DOM से एक तत्व को हटाने का मानक और मुहावरेदार तरीका बन जाएगा।

.remove()2011 ( कमिट ) में डोम लिविंग स्टैंडर्ड में इस विधि को जोड़ा गया था , और तब से इसे क्रोम, फ़ायरफ़ॉक्स, सफारी, ओपेरा और एज द्वारा लागू किया गया है। यह इंटरनेट एक्सप्लोरर के किसी भी संस्करण में समर्थित नहीं था।

यदि आप पुराने ब्राउज़र का समर्थन करना चाहते हैं, तो आपको इसे शिम करना होगा। यह थोड़ा चिड़चिड़ा हो जाता है, क्योंकि दोनों को लगता है कि किसी ने भी एक सर्व-उद्देश्य डोम शिम नहीं बनाया है जिसमें ये विधियां शामिल हैं, और क्योंकि हम केवल एक ही प्रोटोटाइप में विधि नहीं जोड़ रहे हैं; यह एक तरीका है ChildNode, जो केवल कल्पना द्वारा परिभाषित इंटरफ़ेस है और जावास्क्रिप्ट के लिए सुलभ नहीं है, इसलिए हम इसके प्रोटोटाइप में कुछ भी नहीं जोड़ सकते हैं। इसलिए हमें उन सभी प्रोटोटाइपों को खोजने की आवश्यकता है जो वास्तव में इनहेरिट करते हैं ChildNodeऔर वास्तव में ब्राउज़र में परिभाषित होते हैं, और .removeउन्हें जोड़ते हैं।

यहाँ मैं के साथ आया शिम है, जो मैंने 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 या उससे कम में काम नहीं करेगा, क्योंकि IE 8 से पहले DOM प्रोटोटाइप का विस्तार संभव नहीं है । हालांकि, मेरा मानना ​​है कि 2015 की कगार पर ज्यादातर लोगों को ऐसी चीजों की परवाह नहीं है।

एक बार जब आप उन्हें शामिल कर लेते हैं, तो आप elementकेवल कॉल करके DOM से DOM तत्व निकाल सकते हैं

element.remove();

1
बस इसे यहीं छोड़ते हुए: polyfill.io/v2/docs/features/#Element_prototype_remove यदि आप उस
स्वचालित पॉलीफ़िल

4
यह निश्चित रूप से 2017 में ऐसा करने का तरीका है जब तक आप IE के बारे में परवाह नहीं करते हैं। देखें: developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove
nevf

45

लगता है कि मेरे पास एक टिप्पणी पोस्ट करने के लिए पर्याप्त प्रतिनिधि नहीं है, इसलिए एक और जवाब देना होगा।

जब आप removeChild () का उपयोग करके एक नोड को अनलिंक करते हैं या पैरेंट पर इनर HTML प्रॉपर्टी सेट करके, आपको यह भी सुनिश्चित करना होगा कि इसे संदर्भित करने के अलावा और कुछ नहीं है अन्यथा यह वास्तव में नष्ट नहीं होगा और मेमोरी लीक को जन्म देगा। ऐसे कई तरीके हैं जिनसे आप removeChild () को कॉल करने से पहले नोड के लिए एक संदर्भ ले सकते हैं और आपको यह सुनिश्चित करना होगा कि जो संदर्भ दायरे से बाहर नहीं गए हैं वे स्पष्ट रूप से हटा दिए गए हैं।

डौग क्रॉकफोर्ड यहाँ लिखते हैं कि ईवेंट हैंडलर को IE में परिपत्र संदर्भों का एक कारण कहा जाता है और उन्हें हटाने से पहले स्पष्ट रूप से हटाने का सुझाव देता है जैसे कि कॉलहिल्ड ()

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 में मेमोरी लीक प्राप्त कर सकते हैं जैसा कि यहां जेन्स-इनगो फारले द्वारा वर्णित किया गया है

और अंत में, इस सोच के जाल में न पड़ें कि जावास्क्रिप्ट डिलीट का उत्तर है। यह कई लोगों द्वारा सुझाया गया लगता है, लेकिन यह काम नहीं करेगा। यहाँ समझने पर एक महान संदर्भ है हटाने Kangax द्वारा।


1
शायद आप इस बात का सबूत देने के लिए कुछ jsField दिखा सकते हैं। धन्यवाद
Muhaimin

1
मैं इस व्यवहार की पुष्टि करता हूं। मेरा ढांचा डोम लेआउट पर एक जावास्क्रिप्ट ऑब्जेक्ट मैपिंग ट्री का उपयोग करता है। प्रत्येक js ऑब्जेक्ट अपने प्रमुख तत्व को संदर्भित करता है। भले ही मैं element.parentNode.removeChildतत्वों को हटाने के लिए कॉल करता हूं , वे जीवित रहते हैं और अभी भी संदर्भित हो सकते हैं। वे सिर्फ नियमित डोम के पेड़ में दिखाई नहीं दे रहे हैं।
सेबस

हां, और फिर उस जेएस मैपिंग ऑब्जेक्ट के लिए ग्लोबल पॉइंटर को हटाकर जादुई रूप से कचरा कलेक्टर को अनलॉक करता है। यह स्वीकृत उत्तर के लिए एक महत्वपूर्ण अतिरिक्त है।
सेबास

11

Node.removeChild () का उपयोग आपके लिए काम करता है, बस कुछ इस तरह का उपयोग करें:

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

DOM 4 में, हटाने की विधि लागू है, लेकिन W3C के अनुसार एक खराब ब्राउज़र समर्थन है:

DOM. विनिर्देश में नोड नोड () को लागू किया गया है। लेकिन खराब ब्राउज़र समर्थन के कारण, आपको इसका उपयोग नहीं करना चाहिए।

लेकिन अगर आप jQuery का उपयोग कर रहे हैं, तो आप रिमूव मेथड का उपयोग कर सकते हैं ...

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

नए ढांचे में भी जैसे आप किसी तत्व को निकालने के लिए शर्तों का उपयोग कर सकते हैं, उदाहरण के लिए *ngIfकोणीय और प्रतिक्रिया में, विभिन्न विचारों का प्रतिपादन, शर्तों पर निर्भर करता है ...


1
यदि आप createElement का उपयोग करके js में मोडल नोड बना रहे हैं, तो यह सुनिश्चित करें कि इसे हटाने से पहले नोड मौजूद है या नहीं। if (leftSection) {.. आपका कोड} काम करना चाहिए।
अफसान अब्दुलाली गुजराती

0

यदि आप शानदार समारोह का उपयोग करके खुश हैं:

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

DOM से एलिमेंट को पूरी तरह से डिलीट करने के लिए।

डेटा और घटनाओं को हटाने के बिना तत्वों को हटाने के लिए, इसके बजाय इसका उपयोग करें:

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

jQuery के डॉक्स

.remove()विधि डोम से बाहर तत्वों लेता है। उपयोग करें .remove()जब आप तत्व को स्वयं निकालना चाहते हैं, साथ ही इसके अंदर सब कुछ भी। तत्वों के अलावा, सभी बाध्य घटनाओं और तत्वों से जुड़े jQuery डेटा हटा दिए जाते हैं। डेटा और घटनाओं को हटाने के बिना तत्वों को हटाने के लिए .detach()इसके बजाय का उपयोग करें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.