Better event listeners

Andrea Giammarchi andrea.giammarchi at gmail.com
Mon Jan 7 11:02:03 PST 2013


don't get anything you said ... first of all nobody taked about different
objects, you can also create instances for that and you know what you are
listening to, it's your object ... secondly I don't use your IDE and I
don't use auto complete but even if I was, the combination of arrow down
and tab or enter after typing the first char where "a" for addEventListener
is probably not enough is already a longer procedre than using just
element.on( ... try that with your iDE

on is also semantic and inline with DOM Level 0 prefix for inline events so
nothing to learn

Finally, adding a listener for multiple events makes always sense if you
use an object rather than a callback as shown in my example.

Last, but not least, you are missing the fact I agree with you
addEventListener isn't that bad and I've only suggested a simplified and
more powerful contract that is already common in all my use cases ... sure,
these might be different from yours

br




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

> Sure, if you like "click" as a method name and you don't listen for
> "click" on different objects for different purpose because if you do,
> you're back to branching your click code.
>
> Autocomplete is already there in some code editors and WebKitInspector so
> I don't buy the long name to type. Code is read a lot more than it is
> typed, I personally favor readability/understandability over typing speed /
> convenience. I really don't type well and my brain has alway been a
> limiting factor to what I type, not my hands, but maybe it's just me!
>
> Adding a listener for multiple events at once only makes sense if you do
> the exact same thing in all cases and in my experience, it's not that
> frequent that I feel it would need  it's own API.
>
> Thanks,
>
> Benoit
>
> On Jan 7, 2013, at 9:36 AM, Andrea Giammarchi <andrea.giammarchi at gmail.com>
> wrote:
>
> 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/be158762/attachment.html>


More information about the es-discuss mailing list