Gotcha ... so, you've a JS class coupled with the DOM so, since you use IDs, all you need to eventually do is
```js onbutton1click(e) { // ... } onbutton2click(e) { // ... } onbutton3click(e) { // ... } handleEvent(e) { this['on' + e.curentTarget.id + 'click'](e); } ``` I believe you would end up with similar code anyway because without `handleEvent` you would need three different methods anyway. Once again, my examples were answering your first question that was: I'd like to set handlers without needing to store the bound reference each time. Hence all my answers, but I guess it's a matter of personal taste. Anyway, if it has to be native and different from `handleEvent`, the `el.addEventListener('click', this.onClick, {context: this});` variant would be my best pick. Best Regards On Mon, May 9, 2016 at 5:37 PM, Mark Kennedy <mkay...@gmail.com> wrote: > Sorry maybe I'm not explaining this the right way. My original intent is > to lessen the code that I would have to write to achieve multiple event > handlers which do different things on multiple DOM elements when > constructing a class and also REMOVING the event listeners manually. I am > assuming this is a scenario where the DOM elements are outliving their > event listeners (for single page web applications for instance) so they > must be removed manually. Let's say I have five buttons on a page and I > want them all to do something different when they are clicked. > > ```html > <button id="button1">button 1</button> > <button id="button2">button 2</button> > <button id="button3">button 3</button> > ``` > > With your approach, I would have to do this, right? > > ```js > class SomeClass { > constructor() { > let button1 = document.getElementById('button1'); > button1.addEventListener('click', this); > let button2 = document.getElementById('button2'); > button2.addEventListener('click', this); > let button3 = document.getElementById('button3'); > button3.addEventListener('mouseover', this); > }, > > onclick(e) { > // if e.target is button1, > // show modal > // if e.target is button2, > // navigate backwards > // i f e.target is button 3, > // do something else > }, > > onmouseover (e) { > // if e.target is button 3 > // do something else different from the above > } > > handleEvent(e) { > this['on' + e.type](e); > } > ``` > It may just be me confused here, but the above code is much more > overwhelming and much less intuitive than the solutions I've proposed above. > > Hopefully this helps clarify a few things. > > > On Mon, May 9, 2016 at 12:20 PM Andrea Giammarchi < > andrea.giammar...@gmail.com> wrote: > >> Hi Mark, not sure I understand. What you are doing is exactly the same, >> there is no difference whatsoever with what I've shown to you. >> >> > Yes but what happens when you have multiple event targets using the >> same `type` of event? You're going to require a lot of extra conditionals >> in `onclick` method. Again this approach is cumbersome and, imo, not the >> most efficient. >> >> conditionals what? the onclick is called only when the node where you >> attached the listener as instance gets invoked. It never triggers in any >> other cases. >> Or better, it is exactly the same as `someNode.addEventListener('click', >> (e) => this.onClick(e))` ... really, PRECISELY the same. >> >> Whenever your `click` gets triggered, the `handleEvent` would behave >> **exactly** the same. Not sure I've stressed the *exactly* part enough so >> nothing is cumbersome, maybe you don't understand or you've never used this >> approach before. >> >> Otherwise, please show me a single example where adding a listener as >> callback, or bound callback, would be triggered differently from adding an >> instance with an inherited, or own, handleEvent. >> >> Going on ... >> >> > 1. When an arrow function is used as the second parameter to >> `addEventListener`, the language can evaluate and use its scoped context >> ... >> >> This is not going to happen. It's an exception to the arrow that would >> confuse even more about its context. >> >> > 2. Another solution would be if we could maybe pass a method string as >> the second parameter and then an optional context as the fourth parameter >> ... >> >> This is DOM land, since it's about `addEventListener` signature, and I >> would personally vote -1 to that variant. >> >> >> You should really try to understand how `handleEvent` works, IMO. It's >> the sugar you're looking for already since it makes you set any listener >> you want *without* needing to store upfront the bound method: fast, clean, >> simple. >> >> To remove a listener at any time, you don't need to store upfront a bound >> version of the method. >> >> Best Regards >> >> >> >> >> On Mon, May 9, 2016 at 5:05 PM, Mark Kennedy <mkay...@gmail.com> wrote: >> >>> Yes but what happens when you have multiple event targets using the same >>> `type` of event? You're going to require a lot of extra conditionals in >>> `onclick` method. Again this approach is cumbersome and, imo, not the most >>> efficient. >>> >>> These may not be the best solutions but here are a few options I've >>> thought of: >>> >>> 1. When an arrow function is used as the second parameter to >>> `addEventListener`, the language can evaluate and use its scoped context >>> when the same function is used with a subsequent `removeEventListener call, >>> so essentially the following code would work when calling destroy. >>> >>> >>> ```js >>> class MyClass { >>> constructor () { >>> someNode.addEventListener('click', (e) => this.onClick(e)) >>> } >>> >>> onClick (e) { >>> // do something here >>> } >>> >>> destroy () { >>> someNode.removeEventListener('click', (e) => this.onClick(e)) >>> } >>> } >>> >>> ``` >>> >>> 2. Another solution would be if we could maybe pass a method string as >>> the second parameter and then an optional context as the fourth parameter >>> to addEventListener and removeEventListener as follows: >>> >>> >>> ```js >>> class MyClass { >>> constructor () { >>> someNode.addEventListener('click', 'onClick', {}, this) >>> } >>> >>> onClick (e) { >>> // do something here >>> } >>> >>> destroy () { >>> someNode.removeEventListener('click', 'onClick', {}, this) >>> } >>> } >>> >>> ``` >>> >>> >>> On Mon, May 9, 2016 at 9:52 AM Andrea Giammarchi < >>> andrea.giammar...@gmail.com> wrote: >>> >>>> uhm, I've used commas ... anyway, the sugar is desugaring to old >>>> methods, this is working example: >>>> >>>> ```js >>>> class SomeClass { >>>> constructor(someNode) { >>>> someNode.addEventListener('click', this); >>>> } >>>> onclick(e) { >>>> alert(this.constructor.name); // SomeClass >>>> } >>>> handleEvent(e) { >>>> this['on' + e.type](e); >>>> } >>>> } >>>> >>>> new SomeClass(document.documentElement); >>>> ``` >>>> >>>> The difference with your example is that you will always be able to >>>> remove the instance without needing to store upfront every bound listener. >>>> >>>> To know where the `addEventListener` was set you always have the >>>> `e.currentTarget` so basically you have a weakmap between a node and an >>>> object where you can always retrieve the initial node that used the object >>>> through the event, keeping the node clean from "expando" links. >>>> >>>> More sugar than this, I'm not sure what would be. >>>> >>>> You could also have a simple naming convention where every method that >>>> starts with `on` will be set as listener using the current instance, and do >>>> the same, if necessary, on teardown/destroy. >>>> >>>> What kind of sugar would you use otherwise? >>>> >>>> The only proposal discussed so far is `el.addEventListener('click', :: >>>> this.onClick)`, unfortunately that doesn't solve anything because >>>> AFAIK they don't see any advantage in having `::this.onClick === :: >>>> this.onClick` which is what I've raised already as "that's what >>>> developers would expect" but apparently it's too costy or complicated or >>>> ... dunno. >>>> >>>> ¯\_(ツ)_/¯ >>>> >>>> Best Regards >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> On Mon, May 9, 2016 at 2:41 PM, Andrea Giammarchi < >>>> andrea.giammar...@gmail.com> wrote: >>>> >>>>> Raising a concern about `addEventListener` and its context probably >>>>> made me think it was rather a WHATWG concern. >>>>> >>>>> Anyway, I don't know why you had to point out the `class` keyword ... >>>>> I mean .... >>>>> >>>>> ```js >>>>> class SomeClass { >>>>> constructor(someNode) { >>>>> someNode.addEventListener('click', this); >>>>> }, >>>>> onclick(e) { >>>>> alert(this.constructor.name); // SomeClass >>>>> }, >>>>> handleEvent(e) { >>>>> this['on' + e.type](e); >>>>> } >>>>> } >>>>> ``` >>>>> >>>>> There you go >>>>> >>>>> Best Regards >>>>> >>>>> >>>>> On Mon, May 9, 2016 at 2:38 PM, Mark Kennedy <mkay...@gmail.com> >>>>> wrote: >>>>> >>>>>> Wow that's so ironic because [I posted this same idea]( >>>>>> https://github.com/whatwg/dom/issues/245#issuecomment-217816301) >>>>>> (literally >>>>>> copied and pasted) in WHATWG's "DOM land" and they told me this was an >>>>>> es-discuss issue. So which is it? >>>>>> Oh and thanks for the code sample but it uses the old prototypical >>>>>> method >>>>>> of replicating a class by creating a function which is now not the >>>>>> most >>>>>> efficient way (there's the `class` keyword). And I don't see how what >>>>>> you're doing isn't any different from a roundabout way of what I did. >>>>>> I >>>>>> already know about the `handleEvent()` stuff, I like that it's >>>>>> available >>>>>> and its polyfills. They are great, but my original question is to >>>>>> implement >>>>>> sugar so that you don't have to use polyfills or the `handleEvent()`. >>>>>> -- >>>>>> >>>>>> mark >>>>>> >>>>>> Sent while riding a hoverboard... >>>>>> heyimmark.com :) >>>>>> >>>>>> _______________________________________________ >>>>>> es-discuss mailing list >>>>>> es-discuss@mozilla.org >>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>> >>>>>> >>>>> >>>> -- >>> >>> mark >>> >>> Sent while riding a hoverboard... >>> heyimmark.com :) >>> >> >> -- > > mark > > Sent while riding a hoverboard... > heyimmark.com :) >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss