7

I'd like to fire an event when an element is added to the document. I've read the JQuery documentation for on() and the list of events but none of the events seem to concern element creation.

I must monitor the DOM as I do not control when the element is added to the document (as my Javascript is a Chrome Extension content script)

mikemaccana
  • 110,530
  • 99
  • 389
  • 494

4 Answers4

6

I know this is an old question, that already has an answer, but since things have changed, I thought I'd add an updated answer for people landing on this page looking for an answer.

The DOM Mutation Events have been deprecated. According to MDN (regarding DOM Mutation Events):

Deprecated
This feature has been removed from the Web. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.

One should use the new MutationObserver API, which is also more efficient.
(The mutation-summary library now provides a useful inteface to this new API.)

Example usage:

// Create an observer instance.
var observer = new MutationObserver(function (mutations) {
  mutations.forEach(function (mutation) {
    console.log(mutation.type);
  });
});

// Config info for the observer.
var config = {
  childList: true, 
  subtree: true
};

// Observe the body (and its descendants) for `childList` changes.
observer.observe(document.body, config);

...

// Stop the observer, when it is not required any more.
observer.disconnect();
gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • No that's good! I hate that StackOverflow gets so out of date with web tech. I've marked this as the accepted answer. – mikemaccana Nov 04 '13 at 12:04
2

As mentioned, I am not creating my own elements, so firing off an event when I create the element isn't an option.

The best solution to this is the Mutation Observer API, for which the Mutation Summary provides a friendly interface.

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
  • This is so incredibly useful for Chrome extensions. Thanks very much! – Joel Mellon Nov 01 '13 at 19:47
  • 1
    For those who want some quick code to get going: http://stackoverflow.com/questions/19150450/why-dont-mutationobserver-codes-run-on-chrome-30 **Combine the question and accepted answer for working code.** – Joel Mellon Nov 01 '13 at 20:05
1

For the simplest option, you might want to examine LiveQuery which is effectively the 'DOM listener' that you're after. It should be used with caution however, as it has the potential to be quite heavyweight, performance-wise.

If you're preferring to 'roll your own' - with .on() it should work for all current and future elements - but the added elements would need to match the selector. For example, if you wire an event up to all classes of .myClass and you then injected a new element of the same class to the DOM, the event should fire. Effectively, the .on() API rolls-up bind/live/delegate from prior versions of jQuery, the latter two of which work against current and future DOM elements.

SpaceBison
  • 3,704
  • 1
  • 30
  • 44
  • Thanks @SpaceBison. What would rolling my own using on() entail? I'm happy to use livequery if it's necessary but would like to avoid plugins if possible. – mikemaccana Dec 19 '11 at 12:14
  • 1
    If you want to have *custom events* that trigger when an item is added, follow the answer of Luiz Fernando - if you JUST want to use the *built-in events*, but have them fire when an element is created, you'll need a selector that matches the elements that already exist and that will be created, and wire them up using *on()* - as long as the new elements match the selector the event will fire for any added elements as well as pre-existing. – SpaceBison Dec 20 '11 at 09:10
0

As a complement of @SpaceBison's answer, you can create your own events when you create these elements. For example:

function create_element() {
    // Create an element
    $( 'body' ).append( "<p>Testing..</p>" )
    // Trigger
    $( 'body' ).trigger( 'elementCreated' );
}
function monitor_elements() {
    $("body").on("elementCreated", function(event){
    alert('One more');
    });
}

$(document).ready(function(){

     monitor_elements();

     for (var i=0; i < 3; i++) {
         create_element();
     }

});

Live example: http://jsfiddle.net/9NsAh/

But of course, it's only usefull when you create your own elements.

Frias
  • 10,991
  • 9
  • 33
  • 40