Bug Tracker

Opened 4 years ago

Closed 4 years ago

#14953 closed feature (wontfix)

Add capture parameter to event related methods

Reported by: lrbabe Owned by: lrbabe
Priority: undecided Milestone: 2.next
Component: event Version:
Keywords: Cc:
Blocked by: Blocking:

Description (last modified by lrbabe)

The w3c event model has a capturing and bubbling phase, jQuery 2 should allow both phases to be used when dealing with events. Maybe this feature could be enabled with a build option to make sure people willfully opt in this backward incompatible API.

Personally I find the capturing phase useful when an event handler is set directly on an input, and I want to prevent it to run but cannot modify its code. I can stopPropagation from a parent element only during the capturing phase. It helps dealing with third party scripts and web components.

Change History (10)

comment:1 Changed 4 years ago by lrbabe

Component: unfiledevent
Description: modified (diff)
Milestone: None2.next

comment:2 Changed 4 years ago by dmethvin

Owner: set to lrbabe
Status: newpending

Personally I find the capturing phase useful when an event handler is set directly on an input, and I want to prevent it to run but cannot modify its code.

This sounds a lot like a debugging scenario. If this isn't production, and I sure hope it's not, you can mess with all sorts of jQuery internals to accomplish this or use the special event interface.

I think capturing could be accomplished via #12031. I don't see a reasonable way to add another parameter to our current event APIs without creating a Boolean trap, and they're already messy enough as it is. Thoughts?

comment:3 Changed 4 years ago by lrbabe

Status: pendingnew

No, it's not a debugging scenario, sorry to disappoint :)

Here's a recent example I had to deal with: I use a web component that extends the behavior of an input using the keydown event. The author of the web component didn't use jQuery, and set the listener directly on the input element (in the future, the listener might even be in a shadow DOM). Now I want to keep the web component but prevent this keydown handler to run. AFAIK, the only way to prevent this is to set a keydown handler higher up in the tree and stopPropagation during capture phase.

Using objects as parameters in the event API seems like a good idea, but the API proposed in #12031 isn't very appropriate for this use case. I would use:

$(elem).on({
  mousemove: {
    handler: mousemoveHandler,
    data: data,
    capture: true
  },
  mousedown: {
    handler: mousedownHandler,
    selector: 'li'
  }
});

comment:4 Changed 4 years ago by dmethvin

That adds a whole new signature to .on() for a pretty rare case, I'm not really up for that.

comment:5 Changed 4 years ago by lrbabe

This isn't entirely new since the API already allows

$(elem).on({
  mousemove: mousemoveHandler,
  mousedown: mousedownHandler,
});

The feature matters more than the API to me, but the API proposed in #12031 seems much more different than what we currently have. I'm not sure where the capture property would have gone in this API. Were you suggesting

$(elem).on('mousemove mousedown', {
  mousemove: mousemoveHandler,
  mousedown: mousedownHandler,
  capture: true
});

comment:6 Changed 4 years ago by dmethvin

I was saying the proposed syntax introduces a completely new set of parameter hockey rules. For the .on object case we need to check for a non-function and pull out the arguments a different way, with the goal of carrying a single Boolean value deep into the guts of jQuery.event.add.

Also, there may be impacts elsewhere in the event system if people expect full support for capturing, the current design is totally built around bubbling. Should I be able to .trigger() an event and have my own capturing handler run before any non-capturing ones? What about the special event system, or our own existing use of capturing handlers there?

comment:7 Changed 4 years ago by lrbabe

I guess I'll have to write the code to see how much complexity it adds. .trigger() needs some work, indeed, but I don't think this feature would interfere with special events.

comment:8 Changed 4 years ago by lrbabe

And what about adding this parameter to jQuery.event.add and jQuery.event.remove only, to begin with?

comment:9 Changed 4 years ago by dmethvin

Those are not documented interfaces.

comment:10 Changed 4 years ago by dmethvin

Resolution: wontfix
Status: newclosed

We discussed this in the core meeting today and are pretty convinced this opens up a big can of worms if the goal is to allow capturing events to have equal standing throughout the entire jQuery event system. You're welcome to do an implementation proving us wrong, but it would need to be very small and well tested before we'd land it.

Note: See TracTickets for help on using tickets.