Bug Tracker

Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#11891 closed enhancement (invalid)

catch-all event handler

Reported by: faassen Owned by:
Priority: undecided Milestone: None
Component: unfiled Version: 1.7.2
Keywords: Cc:
Blocked by: Blocking:

Description

In jQuery 1.6.4, registering an event handler on $(document) or $(window) would work as a catch-all event handler, even for events on elements that are not attached to the DOM. In jQuery 1.7 this changed

http://bugs.jquery.com/ticket/10489

See also this jsFiddle demonstrating the difference between 1.7 and 1.6.4; in 1.6.4 this fires twice, but if you switch to 1.7.2 it'll fire only once.

http://jsfiddle.net/jzESV/14/

My code was relying on this catch-all event handling behavior, but broke. I understand why this fix was made, but would it be possible to add a feature to jQuery that would allow the developer to register a catch-all event handler that will be triggered if no element-level (or document level or window level) event handler can be found? This would simplify my code; now I have to check whether the event was handled at all, and if not, trigger the catch-all handler, which is more ugly than I'd like it to be. I don't know what "this" should be in such a handler, but ev.target is still available to do something interesting.

(I tried to look for such a feature in the code but I couldn't find anything - sorry if I missed something.)

Change History (7)

comment:1 Changed 7 years ago by dmethvin

Resolution: invalid
Status: newclosed

That's not at all in keeping with the DOM event model, where events bubble to the document. It sounds like you are trying to implement pub/sub or a callback queue. Look at $.Callbacks or Google for jQuery pub/sub. For more discussion please use the forums.

comment:2 in reply to:  1 Changed 7 years ago by faassen

I want the events to be issued to DOM nodes and to bubble up the DOM tree to the document. But there are two special cases:

  • the node may not be connected to the document.
  • there is still no event handler on the document.

I want the option to catch the event after all in these cases. I.e. a global event handler that gets called if no specific event handler can be found. In jQuery 1.6 I could get away with putting an event handler on the document itself to catch even those events sent to unconnected nodes, but this was changed in 1.7. Now there's no equivalent functionality.

I now solve this by putting a special flag on the event object that indicates whether this is handled at all. The DOM event handlers then set this flag. If the flag isn't set, I trigger the global handler. Since for my use case I'm in charge of triggering the event I can get away with this, that won't work for events triggered by the browser. It also isn't very clean.

I'll take this to the forums too, by referring to this issue.

comment:4 Changed 7 years ago by dmethvin

Add a listener to document and propagate it to your disconnected elements.

comment:5 Changed 7 years ago by faassen

I'm not sure what you're saying.

If you mean to also bind the handler to the disconnected elements, in this case I want *every* element to be able to respond to my custom event. That's what I am doing with a document-level handler. I could create a new element factory that made sure my event handler is attached to each and every created element, but I want this to work with elements created anywhere.

comment:6 Changed 7 years ago by dmethvin

If it is not in the document it cannot receive a bubbled event. Not in jQuery, and not in bare DOM. We are not preventing something that is already in the DOM, you are asking for special-case functionality so expect to write your own special-case code. We're not adding it.

comment:7 Changed 7 years ago by faassen

I'm not suggesting the document should receive the bubbled event; this was the behavior in jQuery 1.6, but this was fixed in jQuery 1.7.

I thought for a moment you said that event bubbling doesn't work for unattached nodes at all and shouldn't, but this jsFiddle demonstrates it does:

http://jsfiddle.net/kXFM8/2/

the 'outer' element handles the event triggered on the 'inner' element, so the event appears to bubble up from outer to inner even though none of these elements are connected. But when these elements bubble up beyond 'outer' without them being handled, there is no way to attach a handler that will catch them.

I realize I'm asking for a new feature, not reporting a bug. This is why this issue is marked 'enhancement'.

Again, ironically doing this was supported by jQuery 1.6 as the aforementioned bug. Upgrading to 1.7 led to the insight that yes, this is bug, but it's useful to be able to do this nonetheless.

I've totally written special case code already; this is not about me having to write less code, just cleaner code. There is a potential use case where someone wants an external library to be able to issue events on disconnected DOM nodes and still handle them in a fallback; in such a case my workaround wouldn't work, as it relies on being in charge of the code that triggers the event.

Last edited 7 years ago by faassen (previous) (diff)
Note: See TracTickets for help on using tickets.