You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functionSomeWidget(elem){this.elem=elem;//Each method needs to be bound to the instance. This also has overhead of creating many functions.this.mousemove=$.proxy(this.mousemove,this);this.click=$.proxy(this.click,this);}SomeWidget.prototype={constructor: SomeWidget,renderTo: function(target){$(target).append(this.elem);$(this.elem).on({click: this.click,mousemove: this.mousemove});},mousemove: function(e){},click: function(e){}};
With jQuery supporting objects as event handlers, it would work like:
gnarf and I talked about this in Austin. It would be a very low-level public interface, ideally the current event features would be built on top of it. Essentially replace this function so we don't go to the current jQuery dispatcher and instead use a caller-supplied dispatching object. That would provide users with low-overhead ways to handle high-frequency events like scroll or mousemove (or the upcoming pointermove) by avoiding jQuery.event.fix() for example.
Additional note re #14953, can we have a way to do capturing here? As I understand the .addEventListener interface it seems like all the events in the attached object would be capturing.
In addEventListener the optional useCapture parameter defines whether capturing is in use regardless if you use a function or an object as a handler. The default is false so in the example all events are bubbling.
Re rwaldron's comment 5 above, I am thinking this interface will be low level enough that we will not support any type of enhancement. That includes special events, delegation, fixing, or additional data. To get those things you'll either need to do them yourself or use the standard interfaces.
For the additional data issue, it's probably not an issue since the this points to an object you get to populate. The other features cost execution time and one of the reasons for this interface is to provide a clean way to get performance when you don't need things like event normalization across browsers.
Some notes on what I've realized/discovered as I've been thinking on this ticket for implementation in 3.0, to write it down somewhere.
Although the object can easily be set up as @petkaantonov describes above, each individual event must be attached via an elem.addEventListener( eventType, handlerFunction, useCapture ) call.
This method is low level but we want it to work properly with methods like .clone( true ) (cloning events to the new element) and .remove() (removing all listeners). The caller cannot set these up through the native addEventListener because jQuery needs to maintain bookkeeping information inside the object.
It's actually possible to attach two handlers per event type, one for each possible useCapture value, so that complicates the bookkeeping.
I'd like to use this interface as the foundation for our existing event layer. We need to define hooks that are called in the object on methods like .clone() or .remove() that can manage the jQuery handlers.
@dmethvin do you plan to finish it in time for 3.0.0? Since this looks like a non-breaking change it seems we could defer it to 3.1.0 (please update the milestone if you agree).
We are currently targeting an event module rewrite that may allow the capture mode among other things for 5.0.0. We originally planned this for 4.0.0 but it didn't make the cut and we didn't want to delay the release any further.
I don't know if this will help, but I wrote a custom EventTarget class back before custom events were allowed. It was written to follow the specification (at that time) exactly, including useCapture. https://github.com/MarkMYoung/EventTargetImpl
So the main obstacle for jQuery is that, almost 20 years ago, there was a decision to have jQuery track all events on a DOM element using the same internal data structure. That made sense (at the time) for performance and cross-browser compatibility reasons. The problem is that now, a particular event handler can have options like capture, once, signal, passive, or other future options, that prevent the use of a multiplexed handler. So, jQuery needs to change its internal data structures to track each event separately with its options, rather than grouping them all together.
This change is complicated because some unknown number of other projects have come to depend on inspecting jQuery's internal data structures to figure out what jQuery handlers are attached to an element. When I looked a few years ago, those projects included the Firefox dev tools. We'd prefer not to break the universe when we add support for new features. Plus, we still have to ensure that jQuery's other event methods like .trigger() and .triggerHandler() continue to work, or document why they no longer work in particular cases.
There are ways to support these new options today in jQuery using custom events, but since the events are multiplexed it means that all the events of the same type on an element will end up having the same options. https://jsbin.com/bupesajoza/edit?html,js,output
I have never wanted capture/passive listeners in frameworks like React or Vue, but they do support them--I had to go look it up to be sure because I'd never needed them! Due to the way elements are defined in markup for those frameworks, it's much less likely that you'd run into the jQuery situation of "select elements and attach a new event handler with an unusual option when there may be handlers on that same element with other options". So if that same one-option-per-element limitation isn't a problem, jQuery's custom event handler isn't a bad solution.
Activity
mgol commentedon Oct 20, 2014
Comment author: dmethvin
Worth thinking about so I'll leave it open.
mgol commentedon Oct 20, 2014
Comment author: rwaldron
I'm into this
http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener
@dmethvin - if you don't mind, I'd like to prototype this one :)
mgol commentedon Oct 20, 2014
Comment author: rwaldron
note to self...
.on({ click: fn })Has to support handling:
// delegated events .on({ click: fn }, "div"); // data object events .on({ click: fn }, "div", dataobject);mgol commentedon Oct 20, 2014
Comment author: dmethvin
Bulk change from enhancement to feature.
mgol commentedon Oct 20, 2014
Comment author: dmethvin
gnarf and I talked about this in Austin. It would be a very low-level public interface, ideally the current event features would be built on top of it. Essentially replace this function so we don't go to the current jQuery dispatcher and instead use a caller-supplied dispatching object. That would provide users with low-overhead ways to handle high-frequency events like scroll or mousemove (or the upcoming pointermove) by avoiding jQuery.event.fix() for example.
mgol commentedon Oct 20, 2014
Comment author: gibson042
A good implementation would make something like https://github.com/jquery/jquery/pull/1367/files significantly more lightweight.
mgol commentedon Oct 20, 2014
Comment author: dmethvin
Additional note re #14953, can we have a way to do capturing here? As I understand the .addEventListener interface it seems like all the events in the attached object would be capturing.
mgol commentedon Oct 20, 2014
Comment author: petka_antonov@…
In addEventListener the optional useCapture parameter defines whether capturing is in use regardless if you use a function or an object as a handler. The default is false so in the example all events are bubbling.
mgol commentedon Oct 20, 2014
Comment author: dmethvin
Re rwaldron's comment 5 above, I am thinking this interface will be low level enough that we will not support any type of enhancement. That includes special events, delegation, fixing, or additional data. To get those things you'll either need to do them yourself or use the standard interfaces.
For the additional data issue, it's probably not an issue since the this points to an object you get to populate. The other features cost execution time and one of the reasons for this interface is to provide a clean way to get performance when you don't need things like event normalization across browsers.
dmethvin commentedon Jan 17, 2015
Some notes on what I've realized/discovered as I've been thinking on this ticket for implementation in 3.0, to write it down somewhere.
elem.addEventListener( eventType, handlerFunction, useCapture )call..clone( true )(cloning events to the new element) and.remove()(removing all listeners). The caller cannot set these up through the nativeaddEventListenerbecause jQuery needs to maintain bookkeeping information inside the object.useCapturevalue, so that complicates the bookkeeping..clone()or.remove()that can manage the jQuery handlers.mgol commentedon Sep 14, 2015
@dmethvin do you plan to finish it in time for 3.0.0? Since this looks like a non-breaking change it seems we could defer it to 3.1.0 (please update the milestone if you agree).
mgol commentedon Sep 16, 2015
@dmethvin Bumped to 3.1.0 but feel free to do it before if you want. ;)
Event: Support EventListener interface objects.
php4fan commentedon Mar 19, 2024
10 years later, is there still no support whatsoever for
useCapture??mgol commentedon Mar 19, 2024
We are currently targeting an event module rewrite that may allow the capture mode among other things for
5.0.0. We originally planned this for4.0.0but it didn't make the cut and we didn't want to delay the release any further.MarkMYoung commentedon Mar 20, 2024
I don't know if this will help, but I wrote a custom
EventTargetclass back before custom events were allowed. It was written to follow the specification (at that time) exactly, includinguseCapture. https://github.com/MarkMYoung/EventTargetImpldmethvin commentedon Mar 21, 2024
So the main obstacle for jQuery is that, almost 20 years ago, there was a decision to have jQuery track all events on a DOM element using the same internal data structure. That made sense (at the time) for performance and cross-browser compatibility reasons. The problem is that now, a particular event handler can have options like
capture,once,signal,passive, or other future options, that prevent the use of a multiplexed handler. So, jQuery needs to change its internal data structures to track each event separately with its options, rather than grouping them all together.This change is complicated because some unknown number of other projects have come to depend on inspecting jQuery's internal data structures to figure out what jQuery handlers are attached to an element. When I looked a few years ago, those projects included the Firefox dev tools. We'd prefer not to break the universe when we add support for new features. Plus, we still have to ensure that jQuery's other event methods like
.trigger()and.triggerHandler()continue to work, or document why they no longer work in particular cases.There are ways to support these new options today in jQuery using custom events, but since the events are multiplexed it means that all the events of the same
typeon an element will end up having the same options. https://jsbin.com/bupesajoza/edit?html,js,outputI have never wanted capture/passive listeners in frameworks like React or Vue, but they do support them--I had to go look it up to be sure because I'd never needed them! Due to the way elements are defined in markup for those frameworks, it's much less likely that you'd run into the jQuery situation of "select elements and attach a new event handler with an unusual option when there may be handlers on that same element with other options". So if that same one-option-per-element limitation isn't a problem, jQuery's custom event handler isn't a bad solution.