Bug Tracker

Opened 2 years ago

Closed 16 months ago

#14595 closed bug (migrated)

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:
Blocked by: Blocking:

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 (30)

comment:1 Changed 2 years ago by anonymous

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

comment:2 Changed 2 years 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 2 years ago by michael@…

Confirmed as above.

comment:4 Changed 2 years 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 2 years 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 2 years ago by timmywil

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

comment:7 Changed 2 years ago by cjqed

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

comment:8 Changed 2 years 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 2 years 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 2 years ago by dmethvin

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

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

comment:11 Changed 2 years 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 2 years ago by dmethvin

  • Resolution notabug deleted
  • Status changed from closed to reopened

comment:13 Changed 2 years 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 2 years 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 2 years 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 2 years ago by anonymous

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

comment:17 Changed 2 years 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 2 years 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 2 years 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 2 years ago by trac-o-bot

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

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 2 years ago by anonymous

I think this bug should be reopened and fixed.

comment:22 Changed 2 years ago by dmethvin

  • Resolution invalid deleted
  • Status changed from closed to reopened

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 2 years ago by dmethvin

  • Status changed from reopened to open

comment:24 Changed 2 years ago by anonymous

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

comment:25 Changed 2 years ago by dmethvin

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

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 2 years ago by anonymous

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

comment:27 Changed 2 years 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 2 years 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 2 years 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 16 months ago by m_gol

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