Bug Tracker

Modify

Ticket #12185 (closed bug: worksforme)

Opened 11 months ago

Last modified 10 months ago

Delegate focus/blur event fires twice

Reported by: andremiguelcruz@… Owned by:
Priority: low Milestone: None
Component: event Version: 1.8.0
Keywords: Cc:
Blocking: Blocked by:

Description

Attaching focus/blur with delegation using a * selector causes handlers to be fired twice on input elements that are within a form.

See:  http://jsfiddle.net/fNEhG/1/

Change History

comment:1 Changed 11 months ago by anonymous

On the fiddle, the first event has currentTarget equal to the element and the second has currentTarget equal to the form.

So the event is bubbling to the form, but shouldn't this be handled in the core? Only one element can have focus at the same time, so it doesn't make much sense to fire one for the input and one for the form.

comment:2 Changed 11 months ago by anonymous

Actually, the event is fired for each DOM up in the tree..

comment:3 Changed 10 months ago by sindresorhus

  • Priority changed from undecided to low
  • Version changed from 1.7.2 to 1.8.0
  • Component changed from unfiled to event

I don't see any reason why you can't just do: $(document.body).on('focus', 'input') or even better $('form').on('focus', 'input').

comment:4 Changed 10 months ago by andremiguelcruz@…

Mainly because elements other then form inputs that can have the focus and blur events (e.g. elements with tabIndex defined)

comment:5 Changed 10 months ago by sindresorhus

You could do: $('form').on('focus', 'input, [tabIndex]')

comment:6 Changed 10 months ago by dmethvin

  • Status changed from new to closed
  • Resolution set to worksforme

This is working correctly as far as I can tell. Delegated events only work with bubbling event types. The focus and blur events are not defined to bubble by the W3C, so as a convenience we translate them to focusin and focusout. There is no other special handling done for focus and blur.

As the event bubbles up from the input, jQuery compares each element to the selector and fires the handler on the element if there is a match. Since * matches everything, each element up the line gets its turn with the handler.

The effect is easier to see with a deeper tree:  http://jsfiddle.net/dmethvin/fNEhG/4/

Or to avoid the red herring about the focus event, here's one with click:  http://jsfiddle.net/dmethvin/fNEhG/5/

Please follow the  bug reporting guidlines and use  jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

View

Add a comment

Modify Ticket

Action
as closed
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.