[Prototype-core] Re: Simple event delegation

2008-02-09 Thread Pat Nakajima

Ok, after working with the syntax I proposed above all day, I'm
inclined to believe a LowPro-esque helper might not be such a bad
thing. Here's the code I'm working with at this point:

  Object.extend(Event, (function(){
return {
  delegate: function(element, eventName, targetSelector, handler)
{
var element = $(element);
function createDelegation(_delegatedEvent) {
  var origin = _delegatedEvent.element();
  if ( origin.match(targetSelector) ){ return
handler(_delegatedEvent); }
};
element.observe(eventName, createDelegation);
return element;
  },

  delegators: function(element, eventName, rules) {
var element = $(element);
function delegateRule(rule) {
  element.delegate(eventName, rule.key, rule.value)
}
$H(rules).each(delegateRule)
return element;
  }
}
  })())

  Element.addMethods({
delegate: Event.delegate,
delegators: Event.delegators
  })

  Object.extend(document, {
delegate: Event.delegate,
delegators: Event.delegators
  })

Event.delegate works in the same way as the syntax I proposed above.
Event.delegators (I'm not too keen on that name) works with the same
syntax that you proposed above. I've also added the the two methods to
document.

I'm also working on a way to simulate bubbling for events that don't
natively do so. For example, a form submission would fire the
'form:submitted' custom event. I add the original event that triggered
the custom event as an attribute of the custom event's memo object,
which gives me the liberty to halt the original event down the line if
I choose to do so like this:

  event.memo['originalEvent'].stop();

I don't really think this sort of thing is fit for core, though it's
interesting, and it works very well with the Event delegation code I
proposed above.



On Feb 8, 6:44 pm, Pat Nakajima [EMAIL PROTECTED] wrote:
 That LowPro post was actually what sparked the idea for me. As for the
 syntax you proposed, I prefer my own (though I'm obviously biased),
 because I like how closely it matches Element.observe. This has a
 couple advantages. First, users will be more inclined to make use of
 it since the syntax will be familiar. Second, the current behavior of
 Event.observe specifies one behavior for one event name, on any number
 of elements (through the use of the following pattern:

   $$('.close').invoke('observe', 'click', Behaviors.close)

 I've been using Event.delegate as a replacement for this pattern, so
 rather than include a totally new paradigm (which is already provided
 through the LowPro library, which will probably have delegation
 support soon anyway), I think that the Prototype way would be:

   $('all').delegate('click', Behaviors.close)

 What do you think?

 On Feb 8, 6:19 pm, Nicolás Sanguinetti [EMAIL PROTECTED] wrote:

  I'd normally respond that since adding this feature is only 5 lines
  away, it'd serve well as a plugin. *But*, event delegation is usually
  such a good practice that adding this to core could be a nice
  incentive for all those people that come into #prototype asking why do
  my 51238 cells in the table take so much to observe an event :)

  I'm not sure if I like the syntax yet, maybe something more LowPro-ish
  as artemy suggested could be nicer

  element.delegate(click, {
    .close: Behaviors.close,
    .send_friend: Behaviors.sendToFriend,
    ...

  });

  (and probably a global document.delegate or Event.delegate that used
  the body as the target element)

  BTW, and speaking about LowPro, Dan blogged earlier today about this
  same thing, but in 
  jquery:http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery

  Thoughts?
  -Nicolas

  On Feb 8, 2008 9:02 PM, Pat Nakajima [EMAIL PROTECTED] wrote:

   I guess I'll have to simulate non-bubbling events (though that
   shouldn't be too painful due to Prototype's custom events). In the
   meantime, I've submitted a patch containing pretty much the code I've
   included above, as well as unit 
   tests:http://dev.rubyonrails.org/ticket/11060

   On Feb 8, 4:07 pm, artemy tregoubenko [EMAIL PROTECTED]
   wrote:

On Fri, 08 Feb 2008 23:48:10 +0300, Pat Nakajima [EMAIL PROTECTED] 
wrote:

 Ah, good point. I've updated my code to reflect your advice:

   Object.extend(Event, {
     delegate: function(element, eventName, targetSelector, handler) {
       var element = $(element);
       element.observe(eventName, function(_delegatedEvent) {
         var origin = _delegatedEvent.element();
         if ( origin.match(targetSelector) ){
           return handler(_delegatedEvent);
         }
       })
     }
   })

 I've looked into the Behaviour library, and used LowPro quite
 extensively. The trouble is that these libraries (correct me if I'm
 wrong) is that they require some sort of refresh if elements are added
 to the page dynamically, 

[Prototype-core] Re: Simple event delegation

2008-02-09 Thread Pat Nakajima

Wow, I didn't realize how much more complex this was. Thanks for the
advice.

On Feb 9, 3:30 am, kangax [EMAIL PROTECTED] wrote:
 I've been working on a delegation plugin with syntax like this:

 Event.register(selector, eventName, handler);

 It supports multiple selectors (separated via comma) and an interface
 to unregister events.

 The implementation is NOT as simple as it seems to be. Just to name a
 few gotchas you stumble upon:

 1) When event is caught by a top level element (document in my case),
 its target property points to a down-most clicked element (which is a
 standard bubble-mode behavior) - not only target but ALL the ancestors
 should be matched against as well.
 2) Using selector matching is fine with events like click but is a
 real blocker (speed-wise) when observing mouseover/mouseout (I had to
 cache instantiated selectors to make it all faster).
 3) All this custom mess needs to be carefully cleaned up on page
 unload (I'm talking about IE's wonderful GC).

 My point is that this is NOT something to be in a core (or at least
 any time soon), but rather a good candidate for a standalone
 extension.
 I am planning to release this plugin, but wanted to write a nice
 article accompanying it (since many people have never even heard of
 event delegation)

 Best,
 kangax
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---