jQuery - जब कोई तत्व DOM से निकाला जाता है तो ट्रिगर इवेंट


211

मैं यह पता लगाने की कोशिश कर रहा हूं कि जब कोई तत्व पृष्ठ से हटा दिया जाता है तो कुछ js कोड निष्पादित कैसे करें:

jQuery('#some-element').remove(); // remove some element from the page
/* need to figure out how to independently detect the above happened */

क्या इसके लिए किसी घटना को क्रमबद्ध किया गया है, जैसे कुछ:

jQuery('#some-element').onremoval( function() {
    // do post-mortem stuff here
});

धन्यवाद।


1
जिज्ञासा से बाहर, उस तत्व के साथ क्या करना चाहते हैं जिसे हटा दिया गया है?
नैट्रियम

8
मेरे पास एक ऐसा तत्व है जो स्वतंत्र रूप से मेरे द्वारा निकाले गए टुकड़े से खुद को जोड़ता है, इसलिए मैं यह पता लगाना चाहता हूं कि वह टुकड़ा उस तत्व को खत्म करने के लिए कब गया है। मैं पूरी चीज़ को फिर से डिज़ाइन कर सकता था, लेकिन ऊपर से पूरा करने से मुझे बहुत समय (और कोड) की बचत होगी।
sa125

जवाबों:


118

बस की जाँच की, यह पहले से ही JQuery के वर्तमान संस्करण में बनाया गया है:

jQuery - v1.9.1

jQuery UI - v1.10.2

$("#myDiv").on("remove", function () {
    alert("Element was removed");
})

महत्वपूर्ण : यह Jquery UI स्क्रिप्ट (JQuery नहीं) की कार्यक्षमता है , इसलिए आपको इसे काम करने के लिए स्क्रिप्ट (jquery और jquery-ui) दोनों को लोड करना होगा। यहाँ उदाहरण है: http://jsfiddle.net/72RTz/


11
यह बहुत मददगार था। मुझे पता चला कि यह कार्यक्षमता jQuery UI के "विजेट" घटक के भीतर है यदि आप पूरे UI लाइब्रेरी को डाउनलोड नहीं करना चाहते हैं।
नील

5
क्या यह कहीं भी प्रलेखित है? मैंने अभी-अभी jQuery के UI विजेट डॉक्यूमेंटेशन को देखा और इसका उल्लेख नहीं पाया। देखना चाहेंगे कि क्या यह आधिकारिक रूप से समर्थित है / इसका उपयोग करने के बारे में कोई चेतावनी ...
josh

यह काम नहीं करता है - jQuery 1.10.2 में कोशिश की गई, हालांकि @mtkopone द्वारा नीचे दिया गया जवाब पूरी तरह से काम करता है इसलिए मैं उस प्रश्न के उत्तर को अपडेट करने के लिए मतदान करूंगा
Marcin

20
यह केवल आंशिक रूप से काम करता है। यदि आप removeउस तत्व पर करते हैं तो यह आग लग जाती है, लेकिन यदि तत्व किसी अन्य तरीके से नष्ट हो जाता है, तो यह कहते हुए कि यह काम नहीं करता है।
कार्ल स्मिथ

आप सही हो सकते हैं, शायद इस मामले के लिए अन्य घटना का नाम है। यह बहुत अच्छा होगा यदि आप अपने मामले के लिए jsfiddle नमूना प्रदान कर सकते हैं।
फिलिप मुनिन

195

आप इसके लिए jQuery के विशेष आयोजनों का उपयोग कर सकते हैं ।

सभी सादगी में,

सेट अप:

(function($){
  $.event.special.destroyed = {
    remove: function(o) {
      if (o.handler) {
        o.handler()
      }
    }
  }
})(jQuery)

उपयोग:

$('.thing').bind('destroyed', function() {
  // do stuff
})

पियरे और डिज़ाइनरगय की टिप्पणियों का जवाब देने के लिए परिशिष्ट:

कॉल करते समय कॉलबैक फायर न करने के लिए $('.thing').off('destroyed'), यदि स्थिति बदलें:if (o.handler && o.type !== 'destroyed') { ... }


15
वास्तव में अच्छा समाधान। बेन अल्मन अधिक जानकारी के लिए विशेष घटनाओं के बारे में एक अच्छा लेखन है: benalman.com/news/2010/03/jquery-special-events
antti_s

11
+1 अब तक के इन विशेष आयोजनों को पूरी तरह से याद रखने में सफल रहा है, उपयोगी! राज्य के लिए एक बात बस ऊपर लागू किया है, यह सबसे अच्छा होगा बदलने के लिए होगा o.handler()करने के लिए o.handler.apply(this,arguments)अन्यथा घटना और डेटा वस्तुओं घटना श्रोता के माध्यम से पारित नहीं मिलता।
22

6
जब आप बिना jQuery के तत्वों को हटाते हैं तो यह काम नहीं करता है।
djjeck

5
यह काम नहीं करता है) जब तत्वों को हटा दिया जाता है या ख के बजाय अलग किया जाता है) जब कुछ पुराने गैर-जॉकरी लाइब्रेरी आपके तत्वों को नष्ट करने के लिए इनर HTML का उपयोग करते हैं (जैसा कि djjeck ने कहा)
ME

5
उस हैंडलर को खबरदार करें जब आप $('.thing').unbind('destroyed')वास्तव में कष्टप्रद हो सकते हैं (क्योंकि अनबिन का मतलब है कि हम हैंडलर को नहीं बुलाना चाहते हैं ...)
पियरे

54

आप DOMNodeRemoved घटना (DOM स्तर 3 WC3 कल्पना का हिस्सा) के लिए बाध्य कर सकते हैं।

IE9 में काम करता है, फ़ायरफ़ॉक्स और क्रोम की नवीनतम रिलीज़।

उदाहरण:

$(document).bind("DOMNodeRemoved", function(e)
{
    alert("Removed: " + e.target.nodeName);
});

जब तत्व बाइंडिंग द्वारा सम्मिलित कर रहे हैं, तो आप सूचना भी प्राप्त कर सकते हैं DOMNodeInserted


13
नोट: "किसी दस्तावेज़ में DOM म्यूटेशन श्रोताओं को जोड़ने से गहराई से उस दस्तावेज़ में आगे DOM संशोधनों का प्रदर्शन कम हो जाता है (उन्हें 1.5 - 7 गुना धीमा कर देता है!)।" से: developer.mozilla.org/en/DOM/Mutation_events
मैट क्रिंकलॉव-वोग

1
इसे प्यार करें, हालांकि नोडनेम मेरे लिए शायद ही उपयोगी है। मैं सिर्फ उपयोग करता हूं e.target.classNameया if ($(e.target).hasClass('my-class')) { ...
मीका अलकोर्न 3

यह तत्व पर ही काम नहीं कर रहा है, केवल इसके बच्चे हैं।
Xdg

अद्भुत जवाब! वास्तव में मेरी मदद की!
कीर मजुर

यह उत्पादन में कोड के लिए धीमा और एक बुरा विचार हो सकता है, लेकिन यह एकमात्र तरीका है जो तुल्यकालिक रूप से काम करता है (MutationObserver के विपरीत) और किसी भी नोड के लिए (सिर्फ jQuery के माध्यम से निकाले गए नोड्स नहीं)। यह डिबगिंग के लिए एक बढ़िया विकल्प है।
निश्चितप्ररूपता

38

तत्वों को हटाने के लिए कोई अंतर्निहित घटना नहीं है, लेकिन आप नकली-प्रचलित jQuery के डिफ़ॉल्ट निकालने की विधि से एक बना सकते हैं। ध्यान दें कि कॉलबैक को वास्तव में संदर्भ रखने के लिए हटाने से पहले कॉल किया जाना चाहिए।

(function() {
    var ev = new $.Event('remove'),
        orig = $.fn.remove;
    $.fn.remove = function() {
        $(this).trigger(ev);
        return orig.apply(this, arguments);
    }
})();

$('#some-element').bind('remove', function() {
    console.log('removed!');
    // do pre-mortem stuff here
    // 'this' is still a reference to the element, before removing it
});

// some other js code here [...]

$('#some-element').remove();

नोट: इस उत्तर के साथ कुछ समस्याओं को अन्य पोस्टर द्वारा उल्लिखित किया गया है।

  1. यह तब काम नहीं करेगा जब नोड को html() replace()अन्य jQuery विधियों के माध्यम से हटा दिया जाए
  2. इस घटना से हड़कंप मच गया
  3. jQuery UI ओवरराइड को भी हटा देता है

इस समस्या का सबसे सुरुचिपूर्ण समाधान प्रतीत होता है: https://stackoverflow.com/a/10172676/216941


2
उसके लिए धन्यवाद! एक छोटा सा जोड़: क्योंकि हटाए जाने की घटना के कारण, आप इसे तब भी प्राप्त करेंगे जब कोई बच्चा निकाल दिया जाएगा, इसलिए बेहतर तरीके से हैंडलर लिखें:$('#some-element').bind('remove', function(ev) { if (ev.target === this) { console.log('removed!'); } });
meyertee

3
यह मेरे लिए बॉक्स से बाहर काम नहीं किया - मुझे परिणाम को मूल रूप से वापस करना पड़ा।

1
दरअसल, @ एडम, यह है, लेकिन यह क्रॉस ब्राउज़र संगत है। Meyertee / fturtle के परिवर्धन के साथ यह एक पूरी तरह से विश्वसनीय समाधान है, जब तक आप केवल HTML को संशोधित / खाली करने के बजाय इस विधि के साथ तत्वों को निकालते हैं, कुछ अधिक लचीलेपन के लिए, हां DOM उत्परिवर्तन घटनाएं ठीक हैं, लेकिन मैं उनके बारे में संदेह कर रहा हूं आपको एक ऐप में व्यवसायिक घटनाओं के लिए सुनना चाहिए, न कि उन डोम को जिनकी संरचना आगे के विकास के साथ बदलने की संभावना है। इसके अलावा, DOM उत्परिवर्तन घटनाओं की सदस्यता लेने का मतलब है कि आपका कार्यक्रम संभावित रूप से DOM DOM पदानुक्रम में पिछड़ने के लिए अतिसंवेदनशील है।
विल मॉर्गन

1
सटीकता पर मेरी एकमात्र असहमति का कथन है - 'तत्वों को हटाने के लिए कोई घटना नहीं बनी है' --- वहाँ स्तर 3 डोम घटनाओं को लागू करने वाले ब्राउज़रों के लिए बनाया गया है (जैसा कि मेरे उत्तर में विस्तृत है)।
एडम

4
हालांकि यह 'हटाएं' फ़ंक्शन का उपयोग करके हटाए गए तत्वों का पता लगाएगा, यह अन्य साधनों द्वारा निकाले गए तत्वों का पता लगाने में विफल होगा (जैसे कि jQuery के html, प्रतिस्थापित, आदि का उपयोग करना) कृपया, अधिक पूर्ण समाधान के लिए मेरा उत्तर देखें।
ज़ाह

32

Hooking .remove()सबसे अच्छा तरीका यह संभाल करने के रूप में वहाँ पेज से तत्वों को दूर करने के कई तरीके हैं (उदाहरण के लिए का उपयोग करके कर रहे हैं नहीं है .html(), .replace(), आदि)।

विभिन्न स्मृति रिसाव खतरों को रोकने के लिए, आंतरिक रूप से jQuery jQuery.cleanData()इसे हटाने के लिए इस्तेमाल की गई विधि की परवाह किए बिना प्रत्येक हटाए गए तत्व के लिए फ़ंक्शन को कॉल करने का प्रयास करेगा ।

अधिक विवरण के लिए यह उत्तर देखें: जावास्क्रिप्ट मेमोरी लीक

इसलिए, सर्वोत्तम परिणामों के लिए, आपको cleanDataफ़ंक्शन को हुक करना चाहिए , जो कि वास्तव में jquery.event.destroyed प्लगइन है:

http://v3.javascriptmvc.com/jquery/dist/jquery.event.destroyed.js


cleanDataमेरे बारे में यह अंतर्दृष्टि बहुत उपयोगी थी! बहुत बहुत धन्यवाद, जो :)
पेट्र वोस्ट्रेल

1
अच्छा जवाब, लेकिन फिर भी यह केवल jQuery के तरीकों के लिए काम करता है। यदि आप एक और मंच के साथ एकीकरण कर रहे हैं जो आपके नीचे से "गलीचा बाहर खींच सकता है" - एडम का जवाब सबसे अधिक समझ में आता है।
ब्रॉन डेविस

7

JQuery UI का उपयोग करने वालों के लिए:

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

जॉन रेजिग ने संकेत दिया है कि वह jQuery कोर के भविष्य के संस्करण में इस घटना को लागू करने के विचार के लिए खुला है, लेकिन मुझे यकीन नहीं है कि यह वर्तमान में कहां खड़ा है।


6

केवल jQuery की आवश्यकता है (कोई jQuery UI की आवश्यकता है)

( मैंने इस एक्सटेंशन को jQuery UI फ्रेमवर्क से निकाला है )

साथ काम करता है: empty()और html()औरremove()

$.cleanData = ( function( orig ) {
    return function( elems ) {
        var events, elem, i;
        for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
            try {

                // Only trigger remove when necessary to save time
                events = $._data( elem, "events" );
                if ( events && events.remove ) {
                    $( elem ).triggerHandler( "remove" );
                }

            // Http://bugs.jquery.com/ticket/8235
            } catch ( e ) {}
        }
        orig( elems );
    };
} )( $.cleanData );

इस समाधान के साथ आप ईवेंट हैंडलर को भी खोल सकते हैं ।

$("YourElemSelector").off("remove");

कोशिश करो! - उदाहरण

$.cleanData = (function(orig) {
  return function(elems) {
    var events, elem, i;
    for (i = 0;
      (elem = elems[i]) != null; i++) {
      try {

        // Only trigger remove when necessary to save time
        events = $._data(elem, "events");
        if (events && events.remove) {
          $(elem).triggerHandler("remove");
        }

        // Http://bugs.jquery.com/ticket/8235
      } catch (e) {}
    }
    orig(elems);
  };
})($.cleanData);


$("#DivToBeRemoved").on("remove", function() {
  console.log("div was removed event fired");
});

$("p").on("remove", function() {
  console.log("p was removed event fired");
});

$("span").on("remove", function() {
  console.log("span was removed event fired");
});

// $("span").off("remove");

$("#DivToBeRemoved").on("click", function() {
  console.log("Div was clicked");
});

function RemoveDiv() {
  //       $("#DivToBeRemoved").parent().html("");    
  $("#DivToBeRemoved").remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>OnRemove event handler attached to elements `div`, `p` and `span`.</h3>
<div class="container">
  <br>
  <button onclick="RemoveDiv();">Click here to remove div below</button>
  <div id="DivToBeRemoved">
    DIV TO BE REMOVED 
    contains 1 p element 
    which in turn contains a span element
    <p>i am p (within div)
      <br><br><span>i am span (within div)</span></p>
  </div>
</div>

अतिरिक्त डेमो - jsBin


4

मुझे यह उत्तर unbinding (अपडेट यहाँ देखने के बावजूद ) के साथ काम करने के लिए नहीं मिल सका , लेकिन इसके चारों ओर एक रास्ता निकालने में सक्षम था। इसका उत्तर एक 'नष्ट_प्रोक्सी' विशेष घटना का निर्माण करना था जिसने एक 'नष्ट' घटना को ट्रिगर किया। आपने ईवेंट श्रोता को 'नष्ट_प्रोटी' और 'नष्ट' दोनों पर डाल दिया, फिर जब आप अनबाइंड करना चाहते हैं, तो आप 'नष्ट' ईवेंट को अनबाइंड करें:

var count = 1;
(function ($) {
    $.event.special.destroyed_proxy = {
        remove: function (o) {
            $(this).trigger('destroyed');
        }
    }
})(jQuery)

$('.remove').on('click', function () {
    $(this).parent().remove();
});

$('li').on('destroyed_proxy destroyed', function () {
    console.log('Element removed');
    if (count > 2) {
        $('li').off('destroyed');
        console.log('unbinded');
    }
    count++;
});

यहाँ एक बेला है


ब्राउज़र संगतता के बारे में यहाँ क्या है? क्या यह अभी भी काम करता है?
व्लादिस्लाव रास्ट्रुसनी

3

मुझे jQuery के विशेष आयोजनों का उपयोग करके mtkopone का उत्तर पसंद है, लेकिन ध्यान दें कि यह काम नहीं करता है) जब तत्वों को हटाया या b के बजाय अलग किया जाता है) जब कुछ पुराने गैर- jquery पुस्तकालय आपके तत्वों को नष्ट करने के लिए इनर HTML का उपयोग करते हैं


3
मैंने डाउनवोट किया क्योंकि प्रश्न .remove () उपयोग के लिए स्पष्ट रूप से पूछा गया था, अलग नहीं। detachइसका उपयोग विशेष रूप से सफाई को ट्रिगर करने के लिए नहीं किया जाता है क्योंकि तत्व को संभवतः बाद में पुन: व्यवस्थित करने की योजना बनाई गई है। बी) अभी भी सच है और अभी तक कोई विश्वसनीय हैंडलिंग नहीं है, कम से कम चूंकि डोम म्यूटेशन घटनाओं को व्यापक रूप से लागू किया जाता है।
पियरे

4
मुझे यकीन है कि आपने "आलोचक" बैज पाने के लिए ऐसा किया था;)
चारोन एमई

1

मुझे यकीन नहीं है कि इसके लिए एक ईवेंट हैंडल है, इसलिए आपको DOM की एक प्रति रखनी होगी और मौजूदा DOM की तुलना किसी तरह के पोलिंग लूप में करनी होगी - जो काफी बुरा हो सकता है। हालांकि फायरबग ऐसा करता है - यदि आप HTML का निरीक्षण करते हैं और कुछ DOM-बदलावों को चलाते हैं, तो यह थोड़े समय के लिए फायरबग कंसोल में पीले रंग में परिवर्तन को उजागर करता है।

वैकल्पिक रूप से, आप एक फ़ंक्शन हटा सकते हैं ...

var removeElements = function(selector) {
    var elems = jQuery(selector);

    // Your code to notify the removal of the element here...
    alert(elems.length + " elements removed");

    jQuery(selector).remove();
};

// Sample usage
removeElements("#some-element");
removeElements("p");
removeElements(".myclass");

1
इस विचार के लिए +1। यद्यपि आप अधिक मानक jQuery कॉल प्राप्त करने के लिए jQuery (प्लगइन शैली) का विस्तार भी कर सकते हैं, जैसे: $ ('। ItemToRemove')। CustomRemove (); आप इसे भी बना सकते हैं ताकि यह एक कॉलबैक को एक पैरामीटर के रूप में स्वीकार करे।
user113716

1

यह है कि कैसे एक jQuery लाइव हटाने श्रोता बनाने के लिए :

$(document).on('DOMNodeRemoved', function(e)
{
  var $element = $(e.target).find('.element');
  if ($element.length)
  {
    // do anything with $element
  }
});

या:

$(document).on('DOMNodeRemoved', function(e)
{
  $(e.target).find('.element').each(function()
  {
    // do anything with $(this)
  }
});

1
ऐसा करने के लिए स्वतंत्र होना बहुत अच्छा होगा। दुर्भाग्य से यह विश्वसनीय नहीं है, क्योंकि उत्परिवर्तन-घटनाओं को
चित्रित

1

JQuery से "हटाएं" घटना ठीक है, बिना जोड़ के। पैचिंग jQuery के बजाय एक सरल ट्रिक का उपयोग करना समय के लिए अधिक विश्वसनीय हो सकता है।

जिस तत्व के बारे में आप DOM से निकालने वाले हैं, उसमें केवल एक विशेषता जोड़ें या जोड़ें। इस प्रकार, आप किसी भी अपडेट फ़ंक्शन को ट्रिगर कर सकते हैं, जो कि नष्ट होने वाले तत्वों को केवल "do_not_count_n" विशेषता के साथ अनदेखा कर देगा।

मान लीजिए कि हमारे पास कीमतों के अनुरूप कोशिकाओं के साथ एक तालिका है, और आपको केवल अंतिम मूल्य दिखाने की आवश्यकता है: यह तब ट्रिगर होता है जब एक मूल्य सेल हटा दिया जाता है (हमारे पास तालिका की प्रत्येक पंक्ति में एक बटन होता है, जो दिखाया नहीं जाता है यहाँ)

$('td[validity="count_it"]').on("remove", function () {
    $(this).attr("validity","do_not_count_it");
    update_prices();
});

और यहां एक फ़ंक्शन है जो तालिका में अंतिम मूल्य पाता है, पिछले एक का खाता नहीं ले रहा है, अगर यह एक है जिसे हटा दिया गया था। वास्तव में, जब "हटाएं" ईवेंट को ट्रिगर किया जाता है, और जब यह फ़ंक्शन कहा जाता है, तो तत्व अभी तक नहीं हटाया गया है।

function update_prices(){
      var mytable=$("#pricestable");
      var lastpricecell = mytable.find('td[validity="count_it"]').last();
}

अंत में, update_prices () फ़ंक्शन ठीक काम करता है, और उसके बाद, DOM तत्व हटा दिया जाता है।


0

@David उत्तर का संदर्भ:

जब आप किसी अन्य फ़ंक्शन, जैसे, के साथ करना चाहते हैं। html () मेरे मामले की तरह, नए फ़ंक्शन में रिटर्न जोड़ना न भूलें:

(function() {
    var ev = new $.Event('html'),
        orig = $.fn.html;
    $.fn.html = function() {
        $(this).trigger(ev);
        return orig.apply(this, arguments);
    }
})();


0

एडम के उत्तर के विस्तार के लिए आपको डिफ़ॉल्ट को प्रचलित करने की आवश्यकता है, यहाँ एक काम है:

$(document).on('DOMNodeRemoved', function(e){
        if($(e.target).hasClass('my-elm') && !e.target.hasAttribute('is-clone')){
            let clone = $(e.target).clone();
            $(clone).attr('is-clone', ''); //allows the clone to be removed without triggering the function again

            //you can do stuff to clone here (ex: add a fade animation)

            $(clone).insertAfter(e.target);
            setTimeout(() => {
                //optional remove clone after 1 second
                $(clone).remove();
            }, 1000);
        }
    });

0

हम DOMNodeRemoved का उपयोग भी कर सकते हैं:

$("#youridwhichremoved").on("DOMNodeRemoved", function () {
// do stuff
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.