jQuery - Trigger event when an element is removed from the DOM
Solution 1
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/
Solution 2
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') { ... }
Solution 3
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
Solution 4
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.
- This won't work when the node is removed via
html()
replace()
or other jQuery methods - This event bubbles up
- jQuery UI overrides remove as well
The most elegant solution to this problem seems to be: https://stackoverflow.com/a/10172676/216941
Solution 5
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
Related videos on Youtube
sa125
Updated on August 11, 2021Comments
-
sa125 over 2 years
I'm trying to figure out how to execute some js code when an element is removed from the page:
jQuery('#some-element').remove(); // remove some element from the page /* need to figure out how to independently detect the above happened */
is there an event tailored for that, something like:
jQuery('#some-element').onremoval( function() { // do post-mortem stuff here });
-
Natrium about 14 yearsout of curiousity, what would want to do with the element that has been removed?
-
sa125 about 14 yearsI have an element that independently attaches itself to the piece I remove, so I want to detect when that piece is gone to eliminate that element as well. I could re-design the whole thing, but accomplishing the above will save me a lot of time (and code).
-
-
user113716 about 14 years+1 for this idea. Though you could also extend jQuery (plugin style) in order to get a more standard jQuery call like: $('.itemToRemove').customRemove();. You could also make it so that it accepts a callback as a parameter.
-
meyertee about 13 yearsThanks for that! One little addition: because the remove-event bubbles up, you'd also receive it when a child is removed, so better write the handler that way:
$('#some-element').bind('remove', function(ev) { if (ev.target === this) { console.log('removed!'); } });
-
fturtle almost 13 yearsThis didn't work out of the box for me - I had to return the result from orig.apply.
-
Rob over 12 yearsThis is not an accurate answer. See my answer
-
Will Morgan over 12 yearsActually, @Adam, it is, but it's cross browser compatible. With meyertee/fturtle's additions it's a perfectly reliable solution, as long as you only remove elements with this method, rather than modifying/emptying HTML etc. For something more flexible, yes DOM mutation events are fine but I've been sceptic of them as you should be listening for business events in an app, not DOM ones whose structure is likely to change with further development. Also, subscribing to DOM mutation events means your program is potentially susceptible to lagging in complex DOM hierarchies.
-
Rob over 12 yearsMy only diagreement on the accuracy is the statement - 'there is no built in event for removing elements' --- there IS a built in event for browsers that implement Level 3 DOM events (as detailed in my answer).
-
Kai Aragaki over 12 yearsWhile this will detect elements removed using the 'remove' function, it will fail to detect elements removed by other means (e.g. using jQuery's html, replace, etc). Please, see my answer for more complete solution.
-
Petr Vostrel about 12 yearsThis insight about
cleanData
was very helpful to me! Thank you very much, Joe :) -
antti_s about 12 yearsReally nice solution. Ben Alman has a nice writeup about special events for more info: benalman.com/news/2010/03/jquery-special-events
-
Matt Wonlaw almost 12 yearsNote: "Adding DOM mutation listeners to a document profoundly degrades the performance of further DOM modifications to that document (making them 1.5 - 7 times slower!)." from: developer.mozilla.org/en/DOM/Mutation_events
-
Matt Wonlaw almost 12 yearsThere are numerous problems with this answer. I'd suggest using the approach outlined by @mtkopone below. stackoverflow.com/a/10172676/216941
-
Micah Alcorn over 11 yearsLove this, although nodeName is rarely useful for me. I just use
e.target.className
orif ($(e.target).hasClass('my-class')) { ...
. -
Pebbl over 11 years+1 had managed to completely miss these special events till now, darn useful! One thing to state having just implemented the above, it would be best to change
o.handler()
too.handler.apply(this,arguments)
otherwise the event and data objects don't get passed through the event listener. -
Bron Davies over 11 yearsNice answer, but still that only works for jQuery methods. If you are integrating with another platform that can "pull the rug out" from under you - Adam's answer makes the most sense.
-
Eat at Joes over 11 yearsagreed, this is the best solution to the question.
-
djjeck over 11 yearsThis doesn't work when you remove elements without jQuery, though.
-
Charon ME over 11 yearsthis doesn't work a) when elements are detached instead of removed or b) when some old non-jquery libraries use innerHTML to destroy your elements (similar to what djjeck said)
-
Pierre over 11 yearsBeware that handler is called when you
$('.thing').unbind('destroyed')
which could really be annoying (since unbind means we do not want the handler to be called...) -
Andy Fleming about 11 years@Pierre - Is there a fix for that?
-
mtkopone about 11 yearsPierre and @DesignerGuy: added an addendum to the original answer for handling the case where you don't want a callback when unbinding the handler
-
Neil almost 11 yearsThis was very helpful. I learned that this functionality is within the "Widget" component of jQuery UI if you aren't looking to download the whole UI library.
-
Pierre almost 11 yearsI downvoted because the question asked explicitly for .remove() use, not detach.
detach
is used especially to not trigger cleanup since the element is probably planned to be reattached later. b) is still true and has yet no reliable handling, at least since DOM mutation events be implemented widely. -
Charon ME almost 11 yearsI bet you did this just to get the "critic" badge ;)
-
josh almost 11 yearsIs this documented anywhere? I just looked through the jQuery UI widget documentation and couldn't find a mention of this. Would like to see whether this is officially supported / any caveats about using it...
-
Marcin over 10 yearsThis one doesn't work - tried in jQuery 1.10.2, however the answer below by @mtkopone works perfectly therefore I would vote for updating the answer in that question
-
Carl Smith over 10 yearsThis one only partly works. If you do
remove
on the element it fires, but if the element is destroyed some other way, by being overwritten say, it doesn't work. -
Philipp Munin over 10 yearsYou might be right, probably there is other event name for this case. It would be great if you can provide jsfiddle sample for your case.
-
Bill Johnston almost 10 years
o.type
seems to be returning'destroyed'
every time soif (o.handler && o.type !== 'destroyed')
isn't working. Any other ways to stop the callback when calling.off
? Theo
object seems to be exactly the same for a removal from the DOM and.off
jsfiddle.net/billjohnston4/wg4ks/3 -
Bill Johnston almost 10 years@mtkopone yeah, I answered with a workaround here
-
EricP over 9 yearsDOMNodeRemovedFromDocument seems to not be supported in Firefox. Perhaps try MutationObserver instead?
-
Eric Holmes about 9 yearsGreat special event. Any way to make it usable with
$('body').on('destroy', '.target', func)
rather than$('.target'.).on('destroy', func)
?? -
jdhildeb over 8 yearsmtkopone's solution below works well and does not require jquery UI.
-
user2700551 over 8 yearsJust a precision, the alert will be triggered right before the div is removed. This listener is called right before the action, so keep in mind that the div is still referenced in the DOM at this time. I had a case when I removed a line from a table and needed to update the display (line number), but it is not working because of that.
-
Xdg about 8 yearsThis is not working on element itself, only its children.
-
Vladislav Rastrusny over 7 yearsWhat about browser compatibility here? Does it still work?
-
Buzogany Laszlo over 7 yearsIs it possible to do it as live event? I need this, but not working: $('body').on('remove', '.selector', function() { ... });
-
Legends about 7 yearsThe remove event is also triggered when content is removed using
html()
, at least with jQuery 3.1 -
Legends about 7 yearsThis even works with
.html("")
. @BuzoganyLaszlo trydocument
instead ofbody
-
Kir Mazur about 7 yearsAmazing answer! Really helped me!
-
Kamafeather almost 7 yearsIt would be great to be free to do that. Unfortunately it is not reliable, as the mutation-events are being deprecated: developer.mozilla.org/en-US/docs/Web/Guide/Events/…
-
Qian Chen about 6 yearsI don't understand why the Addendum would work. The
o.type==='destroyed'
should always be true, no matter throughoff()
,unbind()
, orremove()
, isn't it? I mean if you modify the if statement according to the addendum, when the element isremove()
d, thedestroyed
callback will not be fired since the whole thing is utilizing the side effect that when an element gotremove()
d, all its events get unbound. -
CertainPerformance about 5 yearsIt may be slow and a bad idea for code in production, but this is looks like the only method that works synchronously (unlike MutationObserver) and for any node (not just nodes removed via jQuery). This is a great option for debugging.
-
Backo about 5 years@CarlSmith and @PhilippMunin, what is the event name e.g. when using jQuery
replaceWith
? -
Sam almost 4 yearsI like this method, the only problem is that I want to trigger removed event using
$(e.target).trigger('remove')
, but the event never trigger :( -
ZalemCitizen over 2 yearsAs Kamafeather comment it here below, MutationEvents should not be used : developer.mozilla.org/en-US/docs/Web/API/…
-
Den Pat over 2 years@ZalemCitizen yes, it should not be used but please show other alternatives. also even it says deprecated, it still works for most browsers.
-
Aaron Digulla over 2 years