4

I want to trigger an event when a specific element appears on a page (I don't control the source page - this isa Chrome extension)

I have read the docs about JQuery 1.7's on() method. However it seems to be about waiting for a specific event to be triggered on the selector - click events - rather than just generally when an element matching the selector is added.

Equivalent in the now-unmaintained livequery plugin:

$('a').livequery(function () {
  console.log('yaay a link was added');
})
mikemaccana
  • 110,530
  • 99
  • 389
  • 494
  • I hit that problem too: http://stackoverflow.com/questions/11716536/bind-the-datepicker-to-new-input-elements – Samson Aug 01 '12 at 11:10

2 Answers2

3

If this is a chrome extension designed for Chrome 18+ then you can use a feature from the DOM4 specification called Mutation Observers. This assigns a callback that is fired when ever the DOM is changed, which you can then use to do what ever you want. It's still pretty new, but there is a bit more info here

Code sample from that page:

var insertedNodes = [];
var observer = new WebKitMutationObserver(function(mutations) {
 mutations.forEach(function(mutation) {
   for (var i = 0; i < mutation.addedNodes.length; i++)
     insertedNodes.push(mutation.addedNodes[i]);
 })
});
observer.observe(document, { childList: true });
console.log(insertedNodes);

Update: Also just noticed a library based on this API, which might be easier to use.

Dan Smith
  • 5,685
  • 32
  • 33
  • Great answer, but alas the sample code doesn't actually seem to fire when I add an event to the DOM. Edit: going to try this library... – mikemaccana Aug 01 '12 at 11:39
  • I must admit I've never tried the code, this answer was mostly based on that article - I assume you are using Chrome 18 or above? – Dan Smith Aug 01 '12 at 11:50
  • The library is working fine, question considered answered. Thanks! – mikemaccana Aug 01 '12 at 12:18
1

How .livequery() works

.livequery() has two uses:

  • when you pass event type as the first argument,
  • when you pass callback (function) as the first argument,

In the first case you are completely able to replace it with currently used .on() or already deprecated .delegate() of .live() (if you have version of jQuery older than 1.7).

In the second case it looks like .livequery() overrides standard DOM modification JS methods, or "hooks" itself into them. To mimic that behaviour you will need to do something similar or just redesign your script to avoid that obstacle.

In case you choose using your own implementation, just make sure you don't make the same mistake as .live() developers did: move selector from the jQuery argument into your module's function's argument: jQuery(selector).live(...) -> jQuery(...).on(..., selector, ...), as does not need to be executed at the time you prepare your script (it is only executed when something changes).

Listening to new elements added into DOM

You are out of luck, because there are not widely adopted events responsible for listening to new DOM elements being inserted into DOM. The list of possible events you can use is here:

https://developer.mozilla.org/en/DOM_Client_Object_Cross-Reference/DOM_Events

Tadeck
  • 132,510
  • 28
  • 152
  • 198
  • @nailer: I have just found another use case for `.livequery()`, which is the case when you pass a function to it. This seems to be based on overriding standard DOM modification JS methods (`.append()`, `.addClass()` etc., as mentioned on their page), so you should probably follow that way, if that functionality is really necessary and cannot be replaced with something more standard. – Tadeck Aug 01 '12 at 11:37