Better event listeners

Andrea Giammarchi andrea.giammarchi at gmail.com
Mon Jan 7 09:36:00 PST 2013


no need to have the big switch in the object ... if you use that object to
register the event you can simply handle that event through the object
itself ... i.e.

var handler = {
  handleEvent: function (e) {
    this[e.type](e);
  },
  click: function click(){},
  touchstart: function touchstart(){} ...
};

anynode.addEventListener("click", handler, false);

or

Object.keys(handler).forEach(function add(key){
  key !== "handleEvent"&& this.addEventListener(key, handler, false);
}, element);

Said that, the problem with functions can be easily solved as well through
bound methods:
http://webreflection.blogspot.de/2012/11/my-name-is-bound-method-bound.html

In any case I agree with you add/removeEventlistener ain't that bad but is
way too boring type that long name each time and you cannot add multiple
events at once which is, with the object and handleEvent, boring as well so
my proposal is same contract slightly improved ;-)

br



On Mon, Jan 7, 2013 at 9:12 AM, Benoit Marchant <marchant at mac.com> wrote:

> Hi there
>
> I have to say I'm really surprised that efforts are spent offering an
> alternative to addEventListener/removeEventListener. I've been doing
> JavaScript development for almost 13 years and I never felt these 2 api
> were that bad.
>
> What is the rationale behind trying to offer an alternative syntax? As
> Francois mentioned, where did capture flag go?
>
> Also we spent years explaining people to not use inline
> onclick="function(e){}" and now it's suddenly ok to do an
> element.on({click: ….) . That's muddying the waters to say the least.
>
> There are other issues that I'm not sure are being worked on:
> - How about a better way when your handlers are objects and not functions?
> The big problem with functions is removing the listeners, it has to be the
> same function object and there are countless leaks today of people not
> realizing that their removeEventListener, when they thought of doing it
> actually doesn't do anything.
> Using an object as a listener typically doesn't have that problem in a
> well organized code like MVC. An object has a role, it's here to stay, it's
> typically "this" in addEventListener/removeEventListener. But "handleEvent"
> is insufficient because then your handleEvent becomes a big switch. In our
> framework we adopted a very intuitive convention and do some event
> distribution ourselves:
> if anObject listen for a "click" in bubble mode for an event target with
> an identifier property of "submitButton" then we look for a method on the
> listener: handleSubmitButtonClick. We shift the routing out of everyone
> else's code, and reading your own code tells you exactly what's going on.
> A more generic way to do that would be to allow the listener registration
> to provide the name of the method he wants as a callback instead of
> "handleEvent".
>
> - Perfornance. Event Delegation as a concept has been pushed because it's
> slow to install all these listeners upfront. Is that being worked on?
>
> - Registering the same listener for multiple different events could be
> useful sometimes
>
> - the API for creating and dispatching events are quite bad in the other
> hand, these need work.
>
>
> Thanks,
>
> Benoit
>
>
> On Jan 7, 2013, at 9:05 AM, Andrea Giammarchi <andrea.giammarchi at gmail.com>
> wrote:
>
> element.on.{EventType} doesn't scale much with custom events where
> prefixes are in place, i.e. "jquery:transform" or whatever other string
> used to create unobtrusive custom events or ... will it? Same is for
> element.on({EventType:cb|handler})
>
> My best version of on follows same addEventListener signature except it
> returns the element itself and accepts an array of types as overload
>
> element.on(
>   type:string|string[],
>   handler:Function|Object (with handleEvent),
>   capture:Boolean (false by default)
> ):element
>
> the counter part is semantically easy to remember ...
>
> element.off(
>   ... same as above ...
> ):element
>
> the ability to reuse a single callback or object with handleEvent together
> with the ability to use arrays of event types makes state machine like
> event driven interaction a piece of cake, IMHO.
>
>
> My 2 cents
>
>
>
>
>
>
>
>
>
> On Mon, Jan 7, 2013 at 8:42 AM, François REMY <
> francois.remy.dev at outlook.com> wrote:
>
>> Hi Anne,
>>
>> Thanks for bringing the case of event registration, this has been a pain
>> in DOM/JavaScript for some time already and it's quite clear we can do
>> better in this area.
>>
>> However, I've a few issues with your latest proposal:
>>
>>    - how do you register more than one handlers for an event?
>>    - how do you unregister an handler with this proposal?
>>    - how do you specify properties for your handlers (like shouldCapture)?
>> and
>>    - isn't creating an object bag a too high cost for an event
>> registration?
>>    - how do you deal with private names and inherited properties?
>>
>> What about resurrecting .{} instead?
>>
>>    element.on.{
>>        click.{
>>            remove(oldCallback1)
>>            add(newCallback1)
>>        }
>>        resize.add(newCallback2)
>>    }
>>
>> Even if .{} isn't resurrected, I think an 'on' proxy still leaves you
>> with a fairly good syntax:
>>
>>    element.on.DOMContentLoaded.**remove(...).add(...).add(...);
>>
>> If we define "element.on" as a proxy, we can event make it support
>> unknown event names by returning an "event handler object" for the event
>> whose name as been specified as property name.
>>
>> That would leave us with two new WebIDL interfaces, and an updated one:
>>
>>    interface EventTarget {
>>        readonly EventRegistrationHub on;
>>    }
>>
>>    interface EventRegistrationHub {
>>        readonly EventTarget target;
>>        /* proxy, returns an event handler for unknown properties whose
>> target is 'target' and whose 'name' is the required property name */
>>    }
>>
>>    interface EventHandler {
>>        readonly DOMString name; // the name of the event
>>        readonly EventTarget target; // the target of the event
>>        add(callback, options...) // ...
>>        remove(callback...) // ...
>>    }
>>
>> Another benefit is that you could pass an event to a function (now, you
>> have to pass the target and the name, and use target.addEventListener/**removeEventListenee(name,
>> ...)).
>>
>> Another benefit could be that now you can check for the existence of an
>> event by doing if("EventName" in target.on), if we configure the proxy
>> correctly (ie return true only if the event is builtin). New events always
>> come with an uppercase first-letter name so that we can be sure there will
>> be no conflict with future Object.prototype.* builtin properties (if
>> there's not one already with the current names, which I believe is not the
>> case).
>>
>> Last but not least, you can get intellisense (autocompletion) once you
>> typed "element.on." in any sufficiently good IDE/dev tool.
>>
>> Best regards,
>> François
>>
>>
>>
>>
>> -----Message d'origine----- From: Anne van Kesteren
>> Sent: Monday, January 07, 2013 2:25 PM
>> To: es-discuss
>> Subject: Object iteration order
>>
>> In "DOM-land" we're designing new APIs that take objects as arguments.
>> Unless objects meet the criteria in
>> https://mail.mozilla.org/**pipermail/es-discuss/2010-**
>> December/012469.html<https://mail.mozilla.org/pipermail/es-discuss/2010-December/012469.html>
>> invocation of the API method might result in implementation-specific
>> behavior. See also
>> https://www.w3.org/Bugs/**Public/show_bug.cgi?id=20158<https://www.w3.org/Bugs/Public/show_bug.cgi?id=20158>
>>
>> Given the convenience of being able to do something like
>>
>>  element.on({click: callback1, resize: callback2})
>>
>> we're probably going to run with it, but I thought I'd give a heads
>> up. Maybe someone here has a better idea or maybe iteration order will
>> finally be settled on? :-)
>>
>>
>> --
>> http://annevankesteren.nl/
>> ______________________________**_________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/**listinfo/es-discuss<https://mail.mozilla.org/listinfo/es-discuss>
>> ______________________________**_________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/**listinfo/es-discuss<https://mail.mozilla.org/listinfo/es-discuss>
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130107/2453fa19/attachment-0001.html>


More information about the es-discuss mailing list