15

I need to bind event listener to all dynamicaly created elements by given css selector.

In jQuery, that would be

$(".foo").live("click", function(e) {
   // bar
});

Is there any equivalent in Prototype for this?

Rob W
  • 341,306
  • 83
  • 791
  • 678
Jakub Arnold
  • 85,596
  • 89
  • 230
  • 327

2 Answers2

22

This is usually done with Event#findElement:

document.observe('click', function(e, el) {
  if (el = e.findElement('.foo')) {
    // there's your `el`
    // might want to stop event at this point - e.stop()
  }
});
ocodo
  • 29,401
  • 18
  • 105
  • 117
kangax
  • 38,898
  • 13
  • 99
  • 135
  • Most excellent. thx! The documentation I found mentioned that only a tagName was allowed, not a CSS selector. However looking at the Prototype source does confirm that a CSS selector is indeed allowed. – mynameistechno Jan 31 '11 at 18:48
  • Well, this isn't exactly equivalent to jQuery. This binds to the document click and finds the event whereas I believe jQuery triggers on DOM changes and binds events to new elements. It is possible that jQuery **was** doing something like this under the covers, but as of jQuery 1.4, it supports events like hover, so I imagine it is *not* doing something like this under the covers anymore even if it once did. – cgp May 24 '11 at 18:34
  • @altCognito, no this is pretty much how jQuery works under the hood for live-binding since `live` was introduced. jQuery can bind handlers to `document` for events that don't natively propagate because jQuery will manually create and propagate such events. – jangosteve Nov 07 '11 at 21:30
  • @Slomojo that's not a syntax error. `el` needs to be assigned not compared to :) – kangax Sep 08 '13 at 08:55
  • Apologies, reverted, in that case I don't understand how you're identifying that the element clicked, is the one you're after. – ocodo Sep 08 '13 at 08:59
  • `e.findElement('...')` searches ancestor tree of an element you clicked on, until it finds the one satisfying the query. The result is assigned to an element. If nothing is assigned (= element never found), the condition block is never entered. – kangax Sep 08 '13 at 09:15
13

The correct answer to the question is here: http://gurde.com/2011/08/jquery-live-in-prototype/

The equivalent of the jQuery .live() in Prototype is the Event.on() method:

var handler = document.on(
    'click',
    'div[id^="post-"] .attached-post-thumbnail',
    function(event, element) {
        console.log(this);
        console.log(element);
    }.bind(this)
);

handler.stop();
handler.start();

Within the callback, the this keyword will always refer to the original element (in this case document).

Jeff Atwood
  • 63,320
  • 48
  • 150
  • 153
robert
  • 871
  • 8
  • 15
  • I do believe the linked example is wrong. There is no `document.on(...)`, instead you would have to use `Event.on(document, ...)` in the same way. – clockworkgeek Aug 07 '11 at 10:53
  • @clockworkgreek, yes there is. I wouldn't write about it if it wouldn't exist. – robert Aug 07 '11 at 12:16
  • @robert, sorry. I was checking against [api.prototypejs.org](http://api.prototypejs.org/) and there [`document.on`](http://api.prototypejs.org/dom/document/) isn't listed and when checked in the console it returns `undefined`. It turns out the site for Prototype 1.7 is running Prototype 1.6! I had to [check the source](https://github.com/sstephenson/prototype/blob/1fb9728/src/dom/event.js#L1210) to find it is defined. – clockworkgeek Aug 07 '11 at 12:40