67

Say I had a div#parent and I append and remove elements to it using jquery. How would I be able to detect when such an event happens on the div#parent element?

Derek
  • 11,588
  • 25
  • 97
  • 153
  • Possible duplicate of [Event when element added to page](https://stackoverflow.com/questions/7434685/event-when-element-added-to-page) – Heretic Monkey Jan 25 '19 at 17:36

4 Answers4

138

Don't use mutation events like DOMNodeInserted and DOMNodeRemoved.

Instead, use DOM Mutation Observers, which are supported in all modern browsers except IE10 and lower (Can I use). Mutation observers are intended to replace mutation events (which have been deprecated), as they have been found to have low performance due to flaws in its design.

var x = new MutationObserver(function (e) {
  if (e[0].removedNodes) console.log(1);
});

x.observe(document.getElementById('parent'), { childList: true });
Qantas 94 Heavy
  • 15,410
  • 31
  • 63
  • 82
  • 9
    Thanks for answer, but *Mutation Observers* has a bad behaviour: I want to set observer to node which will be attached to tree later. I don't know the parent ( With 'DOMNodeRemoved' I could. Any ideas? I want node listen self destruction. – DenisKolodin Aug 13 '16 at 07:10
  • @DenisKolodin wow, I didn't notice this comment, sorry. For posterity's sake, that should be answered by [this question](https://stackoverflow.com/q/31798816/2074608). It does mean placing an event at the document level, but mutation events have such a large performance penalty it probably doesn't matter anyway. – Qantas 94 Heavy Sep 25 '17 at 12:51
  • 1
    not sure if this is worth mentioning in your answer as it doesn't directly answer this question, but custom elements have a disconnectedCallback – Mr5o1 Jun 06 '20 at 23:33
  • @Qantas94Heavy What do you mean? If performance penalty is real why are we recommended away from DOMNodeRemoved? I am also considering one on document level. Please see https://stackoverflow.com/questions/69426920/javascript-mutationobserver-observing-a-child-element-after-observing-a-parent – mjs Oct 03 '21 at 16:50
  • @mmm as noted by Mr5o1 you could use custom elements. If you can't, you could bind it to the parent and re-bind as that changes: https://stackoverflow.com/q/50391422/2074608 – Qantas 94 Heavy Oct 07 '21 at 02:41
32

Use Mutation Observers as suggested by @Qantas in his answer


Following methods are deprecated

You can use DOMNodeInserted and DOMNodeRemoved

$("#parent").on('DOMNodeInserted', function(e) {
    console.log(e.target, ' was inserted');
});

$("#parent").on('DOMNodeRemoved', function(e) {
    console.log(e.target, ' was removed');
});

MDN Docs

Satpal
  • 129,808
  • 12
  • 152
  • 166
  • 16
    Mutation events are deprecated, this answer should no longer be the correct one. Mutation Observers were _designed as a replacement for Mutation Events_, so Qantas answer is the correct one. https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events and https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver – Parziphal Mar 04 '17 at 23:05
  • used this method, but with config only to listen child dom updated , ref: https://academy.byidmore.com/post/Listen-Added-and-Deleted-Node-in-HTML-DOM-5be15ad61bde484c8fbedd35 – yussan Nov 07 '18 at 00:39
  • It may be slow and a bad idea for code in production, but this looks like the only method that works synchronously (unlike MutationObserver). This is a good option for debugging when nothing else is suitable, for example, when trying to find the line of code that changed the DOM. – CertainPerformance Mar 20 '19 at 03:53
  • @satpal Is it possible to combine these, instead of having two sets of code? If `DOMNodeInserted or DOMNodeRemoved, function() {` etc. – wharfdale Dec 15 '19 at 22:29
  • If performance penalty is real why are we recommended away from DOMNodeRemoved? I am also considering one on document level. Please see https://stackoverflow.com/questions/69426920/javascript-mutationobserver-observing-a-child-element-after-observing-a-parent – mjs Oct 03 '21 at 16:50
3

You should bind DOMSubtreeModified event

$("#parent").bind("DOMSubtreeModified",function(){
  console.log('changed');
});

http://jsfiddle.net/WQeM3/

mdolbin
  • 936
  • 4
  • 8
  • 3
    `DOMSubtreeModified` events are deprecated: [Can I Use](https://caniuse.com/#search=DOMSubtreeModified) – Cody Dec 17 '17 at 01:41
  • 1
    If performance penalty is real why are we recommended away from DOMNodeRemoved? I am also considering one on document level. Please see https://stackoverflow.com/questions/69426920/javascript-mutationobserver-observing-a-child-element-after-observing-a-parent – mjs Oct 03 '21 at 16:50
0

It wouldn't let me comment below on the top answer but to answer your question @DenisKolodin, in order to listen for self-destruction, you can do something like this:

function watchElForDeletion(elToWatch, callback, parent = document.querySelector('body')){
  const observer = new MutationObserver(function (mutations) {

    // loop through all mutations
    mutations.forEach(function (mutation) {

        // check for changes to the child list
        if (mutation.type === 'childList') {

            // check if anything was removed and if the specific element we were looking for was removed
            if (mutation.removedNodes.length > 0 && mutation.removedNodes[0] === elToWatch) {
                callback();
            }
        }
    });
  });

  // start observing the parent - defaults to document body
  observer.observe(parent, { childList: true });
};

It defaults to the parent being the body element and only runs the callback if the specific element you're looking for is deleted.

itsbhenry
  • 1
  • 1
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/31424877) – Ethan McTague Apr 01 '22 at 17:47