Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery - Trigger event when an element is removed from the DOM

People also ask

Are event listeners removed when element is removed?

According to the jquery Documentation when using remove() method over an element, all event listeners are removed from memory. This affects the element it selft and all child nodes. If you want to keep the event listners in memory you should use . detach() instead.

How to use trigger function in jQuery?

jQuery trigger() MethodThe trigger() method triggers the specified event and the default behavior of an event (like form submission) for the selected elements. This method is similar to the triggerHandler() method, except that triggerHandler() does not trigger the default behavior of the event.


You can use jQuery special events for this.

In all simplicity,

Setup:

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

Usage:

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

Addendum to answer Pierre and DesignerGuy's comments:

To not have the callback fire when calling $('.thing').off('destroyed'), change the if condition to: if (o.handler && o.type !== 'destroyed') { ... }


Just checked, it is already built-in in current version of JQuery:

jQuery - v1.9.1

jQuery UI - v1.10.2

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

Important: This is functionality of Jquery UI script (not JQuery), so you have to load both scripts (jquery and jquery-ui) to make it work. Here is example: http://jsfiddle.net/72RTz/


You can bind to the DOMNodeRemoved event (part of DOM Level 3 WC3 spec).

Works in IE9, latest releases of Firefox and Chrome.

Example:

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

You can also get notification when elements are inserting by binding to DOMNodeInserted


There is no built-in event for removing elements, but you can create one by fake-extending jQuery's default remove method. Note that the callback must be called before actually removing it to keep reference.

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

Note: some problems with this answer have been outlined by other posters.

  1. This won't work when the node is removed via html() replace() or other jQuery methods
  2. This event bubbles up
  3. jQuery UI overrides remove as well

The most elegant solution to this problem seems to be: https://stackoverflow.com/a/10172676/216941


Hooking .remove() is not the best way to handle this as there are many ways to remove elements from the page (e.g. by using .html(), .replace(), etc).

In order to prevent various memory leak hazards, internally jQuery will try to call the function jQuery.cleanData() for each removed element regardless of the method used to remove it.

See this answer for more details: javascript memory leaks

So, for best results, you should hook the cleanData function, which is exactly what the jquery.event.destroyed plugin does:

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


For those who use jQuery UI:

jQuery UI has overridden some of the jQuery methods to implement a remove event that gets handled not only when you explicitly remove the given element, but also if the element gets removed from the DOM by any self-cleaning jQuery methods (e.g. replace, html, etc.). This basically allows you to put a hook into the same events that get fired when jQuery is "cleaning up" the events and data associated with a DOM element.

John Resig has indicated that he's open to the idea of implementing this event in a future version of jQuery core, but I'm not sure where it stands currently.