Is there a jquery event that fires when a new node is inserted into the dom?

JqueryHtml

Jquery Problem Overview


Is there an event jquery fires on a dom element when it is inserted into the dom?

E.g. lets say I load some content via ajax and add it to the DOM and in some other piece of javascript I could add an event using .live() so that when an event matching a specific selector is added to the DOM the event fires on said element. Similar to $(document).ready() but on content that is added to the DOM dynamically.

What I am dreaming of:

$('.myClass').live('ready', function() {
    alert('.myClass added to dom');
});

If jquery doesn't support such a thing then is there another way I could achieve this functionality without modifying the code that actually does the initial dom manipulation?

Jquery Solutions


Solution 1 - Jquery

> deprecated: as per @Meglio's comment below, the DOMNodeInserted event is deprecated, and will be removed from the web at some unkown time in the future. For the best results, start learning about the MutationObserver API. > > see @dain's answer below.

If you bind the 'DOMNodeInserted' event to the document or body directly, it will get executed every time anything is inserted anywhere. If you want the callback to run only when a particular kind of element is added, you would be wise to use delegated events.

Usually, if you are adding a class of elements to the DOM you will be adding them to a common parent. So attach the event handler like this:

$('body').on('DOMNodeInserted', '#common-parent', function(e) {
  if ($(e.target).attr('class') === 'myClass') {
    console.log('hit');
  }
});

Basically the same answer as Myke's above, but since you are using a delegated event handler rather than a direct event handler, the code in there will be fired less often.

NOTE:

$('body').on('DOMNodeInserted', '.myClass', function(e) {
  console.log(e.target);
});

This seems to work too... but I don't know why.

Solution 2 - Jquery

The .livequery() plugin still serves this niche need, like this:

$('.myClass').livequery(function() {
  alert('.myClass added to dom');
});

If you pass it just a callback function like above, it'll run for each new element it finds, both initially and as they're added. Inside the function this refers to the just-added element.

.live() listens for events that bubble, so doesn't fit this "when elements are added" situation, in that respect, .livequery() (the plugin) wasn't completely replaced by the addition of .live() to core, only the event bubbling portion (for the most part) was.

Solution 3 - Jquery

If you're living on the cutting edge you can use MutationObserver :)

  var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
  var list = document.querySelector('ol');
 
  var observer = new MutationObserver(function(mutations) {  
    mutations.forEach(function(mutation) {
      if (mutation.type === 'childList') {
        var list_values = [].slice.call(list.children)
            .map( function(node) { return node.innerHTML; })
            .filter( function(s) {
              if (s === '<br>') {
                return false;
              }
              else {
                return true;
              }
        });
        console.log(list_values);
      }
    });
  });
 
  observer.observe(list, {
  	attributes: true, 
  	childList: true, 
  	characterData: true 
   });

See: https://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/

Edit: this answer is quite old, now MutationObserver is supported by all browsers except Opera Mini: http://caniuse.com/#feat=mutationobserver

Also, here's the direct link the the API on MDN: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

Solution 4 - Jquery

There is no jQuery event, but there is a DOM event: DOMNodeInsertedIntoDocument. You can listen for DOM events using jQuery's on method. So:

$('.myClass').on('DOMNodeInsertedIntoDocument', function() {
  alert('myClass was inserted into the DOM');
}

This may be preferable to using liveQuery as that plugin is a bit stale (no updates for 2+ years, only promises support for jQuery 1.2.x).

Solution 5 - Jquery

Take a look at insertionQuery. It's an interesting library that uses CSS to detect new elements. Because it uses CSS there's no performance hit and you get returned the actual elements matching the selector.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question3urdochView Question on Stackoverflow
Solution 1 - JqueryZiggyView Answer on Stackoverflow
Solution 2 - JqueryNick CraverView Answer on Stackoverflow
Solution 3 - JquerydainView Answer on Stackoverflow
Solution 4 - JqueryMyke CameronView Answer on Stackoverflow
Solution 5 - JqueryigneosaurView Answer on Stackoverflow