Bug Tracker

Ticket #14595 (closed bug: migrated)

Opened 11 months ago

Last modified 5 hours ago

textbox not responding to keyup event in IE11

Reported by: sylvain courcoux Owned by: sylvain courcoux
Priority: low Milestone: None
Component: event Version: 1.10.2
Keywords: ie Cc:
Blocking: Blocked by:

Description

Hi,

I have a select element and a textbox element. The textbox is wired with a keyup event handler that checks if the input is numeric using a Regex and clears any non-numeric characters. The textbox is also wired to a focus event handler to check if the value of the select element is numeric and if it's not then blur the textbox. Basically, the functionality is to enter phone numbers.

The problem is that in IE11, non-numeric characters go through whereas is Chrome and Firefox the non-numeric characters are deleted as expected. Not sure if it's a jQuery or an IE11 problem.

The jsFiddle is here:  http://jsfiddle.net/R2Axp/2/

Change History

comment:1 Changed 11 months ago by anonymous

Just to clarify: the non-numeric go through in IE11 when the select element is left non-numeric.

comment:2 Changed 11 months ago by anonymous

BTW, when using jQuery 1.8 and under, the functionality works as expected in IE; it's with versions 1.9 and above that the functionality break in IE.

comment:3 Changed 11 months ago by michael@…

Confirmed as above.

comment:4 Changed 10 months ago by cjqed

I dug into this a little bit, and found the culprit to be a combination of element.blur(); and the .on() handler. See the following jsfiddle:

 http://jsfiddle.net/w2Mm2/2/

Similar to the original commenter's fiddle, on Chrome clicking on both input boxes, neither allow you to enter keys into them because they .blur(); on focus();. The console reads "test2" whenever you click the inputs (as expected). If you take out the .blur(); command, you can type in both inputs and "test1" is console.log'd on keyup, as expected.

In IE11, everything works the same way except when you have .blur() added in (like the fiddle starts with), you can still type in the input box ONLY on the input box whose event handlers were handled with a body.on() call, instead of assigning them directly (jquery.focus(fn)). Another note is that, as per the original ticket report, the keyup function does NOT get called when you input keys into the box.

comment:5 Changed 10 months ago by anonymous

Thanks for looking into it. What's weird is that it all used to work fine in jQuery 1.8

comment:6 Changed 10 months ago by timmywil

@cjqed: Do you mind if we assign this ticket to you?

comment:7 Changed 10 months ago by cjqed

@timmywil Sure, I'll dive into it this weekend.

comment:8 Changed 10 months ago by cjqed

@timmywil So I've made some headway, but before diving deeper I'd like a confirmation. See the following jsFiddle:

 http://jsfiddle.net/DuYAc/57/

Given three options to assign event handlers:

$(selector).focus(function() {
  doSomething();
});

$(selector).on({
  focus: doSomething
});

$(parentSelector).on({
  focus: doSomething
}, selector);

Should each of these three have the same result? Right now, the third option does not leave a function attached to the focus event because ( https://github.com/jquery/jquery/blob/master/src/event.js#L97) is changing the type to the delegate type (focusin, and blur to focusout). Is this the intended behavior for the third way of assigning event handlers?

comment:9 Changed 10 months ago by dmethvin

Only the focusin event bubbles according to the W3C.

 http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent

Use the focusin event if you are using delegation.

comment:10 Changed 10 months ago by dmethvin

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

Yes, this is intended behavior. focusin must be used in event delegation.

comment:11 Changed 10 months ago by anonymous

How can this be marked as resolved when:

a) the jsfiddle clearly demonstrates the bug

b) it used to work just fine in jQuery 1.8

Something broke in jQuery 1.9 and above and this needs to be fixed.

comment:12 Changed 10 months ago by dmethvin

  • Status changed from closed to reopened
  • Resolution notabug deleted

comment:13 Changed 10 months ago by dmethvin

  • Owner set to sylvain courcoux
  • Status changed from reopened to pending

Agreed, this is not the problem.

Original, broken in IE:  http://jsfiddle.net/R2Axp/2/

Working (I think):  http://jsfiddle.net/R2Axp/8/

Does that seem correct?

comment:14 Changed 10 months ago by anonymous

Well the jsFiddle in v8 solves the problem of the functionality not working by changing the code but that doesn't fix the jQuery bug. In IE, the functionality as it was originally coded in the jsFiddle breaks in jQuery 1.9+ and works with older jQuery versions and in other browsers.

comment:15 Changed 10 months ago by dmethvin

I just need confirmation that the change does seem to fix things, since the test case has a lot of moving parts.

This appears to be a consequence of us using the real DOM blur for .trigger("blur") to fix several problems related to event order.

comment:16 Changed 10 months ago by anonymous

Yes, the change on line 25 from TheBox.blur() to TheBox.triggerHandler("blur"); makes the functionality work.

comment:17 Changed 10 months ago by anonymous

No, sorry, just realized that something else is still not working with the change on line 25: the input box should not allow for focus if the select element is not numeric.

comment:18 Changed 9 months ago by dmethvin

I am pretty sure this is the problem with DOM .blur() being essentially async in IE (all versions up to at least 11). I do not think we can work around that but will leave the ticket open for now.

comment:19 Changed 9 months ago by anonymous

Ok, thanks for leaving it open. If the functionality used to work in 1.8 and then stopped working in 1.9 and above them shouldn't it be fixable?

comment:20 Changed 9 months ago by trac-o-bot

  • Status changed from pending to closed
  • Resolution set to invalid

Because we get so many tickets, we often need to return them to the initial reporter for more information. If that person does not reply within 14 days, the ticket will automatically be closed, and that has happened in this case. If you still are interested in pursuing this issue, feel free to add a comment with the requested information and we will be happy to reopen the ticket if it is still valid. Thanks!

comment:21 Changed 9 months ago by anonymous

I think this bug should be reopened and fixed.

comment:22 Changed 9 months ago by dmethvin

  • Status changed from closed to reopened
  • Resolution invalid deleted

If you're the anonymous in comment 20, the reason it auto-closed is that the reply wasn't from a logged in person.

comment:23 Changed 9 months ago by dmethvin

  • Status changed from reopened to open

comment:24 Changed 9 months ago by anonymous

Ok, I'm the "anonymous" in comment 20 but I'm actually the person who filed the bug.

comment:25 Changed 9 months ago by dmethvin

  • Keywords ie added
  • Priority changed from undecided to low
  • Component changed from unfiled to event

N.B, all versions of IE from IE6 upward fire the event asynchronously to the calling of the DOM focus or blur methods.

 http://jsfiddle.net/5g2yV/

What you want to see in the console:

before focusing text1
focus text1
after focusing text1

What you see in IE:

before focusing text1
after focusing text1
focus text1

The reason this used to work is because we faked the focus ourselves, which caused a larger stack of bugs related to event order. See #14359, #13026, and #12868.

comment:26 Changed 9 months ago by anonymous

I can see why this is going to be hard to handle...

comment:27 Changed 9 months ago by anonymous

This might sound a bit of a hack but adding a setTimeout of 1ms for IE reorders the events correctly. So if the jQuery .focus() and .blur() functions could just wait 1ms before returning then that might fix this problem.

 http://jsfiddle.net/5g2yV/2/

comment:28 Changed 9 months ago by dmethvin

Yes, your code can do that. Our  unit tests do that. jQuery cannot do that internally without pushing the problem to another location. The caller could assume that when $(elem).focus() returns the element is focused and it did whatever the event handler was supposed to do. That's why faking the focus event worked, although it had other undesirable effects, because we forced the handler to run right then and there.

The bottom line is that focus/blur is not an event to be trusted. It's async in IE and occasionally unreliable in Firefox as well. Don't create complicated scenarios with it. It will break.

comment:29 Changed 9 months ago by anonymous

It's really unfortunate because the blur and focus events are used in forms and forms are used for important tasks such as user registration or e-commerce processing.

In my particular case, the functionality in the jsFiddle is used to enter international phone numbers: if the user hasn't selected a country code from the select element then it blurs the phone number textbox to force the user to select a prefix first.

I changed my code to make it work but it would really be nice to find a more general solution from within jQuery because inevitably this problem is causing bugs in people's websites, in particular those that were built and tested before 1.9 was released, but that have since then not been maintained.

BTW, are the keyup/keydown events subject to the same unexpected behavior?

comment:30 Changed 5 hours ago by m_gol

  • Status changed from open to closed
  • Resolution set to migrated
Note: See TracTickets for help on using tickets.