11

Is it possible to have a Chrome extension listen for the appearance of a yet-to-be-created element?

Say the user clicks a button and the click event creates an element <div id='myDiv'>My Div</div> and adds it to the page/DOM. Is it possible to set a listener that will automatically fire an event when that element appears?

Or do I have to resort to polling the page and checking for this element every X amount of milliseconds?

jQuery and other libraries are not an option for me btw.

Ry-
  • 218,210
  • 55
  • 464
  • 476
Jim_CS
  • 4,082
  • 13
  • 44
  • 80
  • Why not keep track of the button clicks? Or will it load through other means? – TheZ Jun 20 '12 at 23:04
  • It is actually being created with an AJAX callback but I just phrased it in the most straightforward way for the sake of example. So I have to listen for the creation/appearance of the element. – Jim_CS Jun 20 '12 at 23:28
  • Duplicate? http://stackoverflow.com/questions/7434685/event-when-element-added-to-page ... In any case it looks like the most elegant solution is now deprecated (DOM Mutation Events), but there is a hacky solution posted here: http://stackoverflow.com/questions/6997826/alternative-to-domnodeinserted – Cecchi Jun 21 '12 at 00:43
  • @Cecchi This isn't *quite* a duplicate, since this question specificallly excludes jQuery. – apsillers Jun 21 '12 at 15:52

2 Answers2

14

The new DOM4 MutationObserver can do this. I don't think it's widely supported yet, but luckily enough for you, it is supported in Chrome, as WebKitMutationObserver.

Modified from the linked tutorial page, this listens for mutations everywhere on the page:

var observer = new WebKitMutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        for (var i = 0; i < mutation.addedNodes.length; i++) {
            if(mutation.addedNodes[i].id == "myDiv") {
                // target node added, respond now...
            }
        }
    });
});
observer.observe(document, { subtree: true });

If you can narrow your listening in observer.observe to a more specific element than document, that would give you some performance gain.

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • Is there a legacy implementation? – Zlatko May 13 '13 at 13:39
  • @zladuric Perhaps you might be interested in [Is there a jQuery DOM change listener?](http://stackoverflow.com/questions/2844565/is-there-a-jquery-dom-change-listener/) – apsillers May 13 '13 at 13:54
  • Thanks, but I can't use external libraries. setInterval it will have to remain. – Zlatko May 13 '13 at 14:49
  • @zladuric Despite the question title, the accepted answer to that question doesn't use jQuery. It uses [DOM mutation events](http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents), which are plain old JS. – apsillers May 13 '13 at 15:03
  • This works, but when I use it (in Chrome, for listening to the birth of an element in Gmail), I get an error that says the options object must set at least one of 'attributes', 'characterData', or 'childList' to true. Which is indeed what you need to do to make it work. – Wytze Feb 13 '17 at 09:52
3

You can use arrive.js, it wraps the Mutation Observers api. Usage:

document.arrive(".test-elem", function() {
    // 'this' refers to the newly created element
    var newElem = this;
});
Uzair Farooq
  • 2,402
  • 3
  • 24
  • 37