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, where as a delegation approach does not.
>
> > > > Yes, Behaviour requires refresh, however it can be easily patched to
> > > > use delegation model. I proposed its syntax only : )
>
> > > > > The problem I'm running into with "submit" not working seems to be
> > > > > related to the fact that the "submit" event doesn't bubble. I suppose
> > > > > I could simulate this, though I wonder if there's a better way.
>
> > > > I once had an idea of fighting this issue: watch clicks on inputs and
> > > > thus detect forms on page. This worked for me, but not when buttons
> > > > were clicked programmatically.
>
> > > > > artemy tregoubenko wrote:
> > > > >> No, I refer to delegate() method you've sent here via email.
>
> > > > >> Event.stop() in you code will stop all event, except ones you want
> > > > >> to handle. I.e. when you run body.delegate('click', 'input',
> > > > >> something), all links on page will become unclickable.
>
> > > > >> > Sorry, I'm not even quite sure what that means. Are you referring
> > > > >> > to
> > > > >> > the sample HTML page?
>
> > > > >> > On Feb 8, 2:55�pm, "artemy tregoubenko" <[EMAIL PROTECTED]>
> > > > >> > wrote:
> > > > >> >> I doubt you really want to stop mismatching events : )
>
> > > > >> >> Concerning sugar, you might be interested in syntax of behaviours
> > > > >> >> library
>
> > > > >> >> > Hey, after reading up a bit about event delegation vs. event
> > > > >> >> > handling
> > > > >> >> > (http://icant.co.uk/sandbox/eventdelegation), I put together
> > > > >> >> > this
> > > > >> >> > little bit:
>
> > > > >> >> > � Object.extend(Event, {
> > > > >> >> > � � delegate: function(element, eventName, targetSelector,
> > > > >> >> > handler) {
> > > > >> >> > � � � var element = $(element);
> > > > >> >> > � � � element.observe(eventName, function(event){
> > > > >> >> > � � � � var origin = $(event.target);
> > > > >> >> > � � � � if ( origin.match(targetSelector) ){
> > > > >> >> > � � � � � return handler(event);
> > > > >> >> > � � � � } else {
> > > > >> >> > � � � � � event.stop();
> > > > >> >> > � � � � }
> > > > >> >> > � � � })
> > > > >> >> > � � }
> > > > >> >> > � })
>
> > > > >> >> > � var ElementExtensions = {
> > > > >> >> > � � delegate: Event.delegate
> > > > >> >> > � }
>
> > > > >> >> > � Element.addMethods(ElementExtensions);
>
> > > > >> >> > Now, I'm not the foremost expert on Prototype's event handling,
> > > > >> >> > but I
> > > > >> >> > thought this was a nice little bit of syntactic sugar, and it
> > > > >> >> > seems to
> > > > >> >> > work well enough. Do you think it's fit for core? (If so, I'd
> > > > >> >> > love to
> > > > >> >> > clean it up and write some tests)
>
> > > > >> >> --
> > > > >> >> arty (http://arty.name)
>
> > > > >> --
> > > > >> arty (http://arty.name)
>
> > > > --
> > > > arty (http://arty.name)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Prototype: Core" group.
To post to this group, send email to [email protected]
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
-~----------~----~----~----~------~----~------~--~---