Prevent both blur and keyup events to fire after pressing enter in a textbox

Edit

To prevent both events from firing, you'll have to somehow mark the element before causing it to lose focus. That way, your blur event handler can tell if the event is the subject of a keyup, or if it legitimately lost focus. Something like this:

$(".textbox").live("blur",function (event) {
    if (!$(this).hasClass('keyupping'))
        alert("blur Event fired");
});

$(".textbox").live("keyup",function (event) {
    $(this).addClass('keyupping');
    if(event.keyCode == 13){ // Detect Enter
        alert("KeyUp fired after pressing Enter");
    }
    $(this).removeClass('keyupping');
});

Try it out: http://jsfiddle.net/GRMule/sR6zm/


Original answer

When the event for keyup fires, it prepares to draw the browser alert dialog, which takes focus from the document and applies it to the modal dialog. This causes the blur event to fire.

The blur event is then jumping in and finishing its execution context before keyup knows what hit it.

This is demonstrated by using something that does not take the focus off the element, like console.log: http://jsfiddle.net/GRMule/7vRLW/

The order that events fire is implementation-specific, meaning that you can't rely on Firefox acting like IE. See the spec: http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-eventgroupings. Try the fiddle with alerts in IE, and in this case you'll see that blur does hit before keyup in IE 7 -- and blur doesn't fire in Chrome!


I have an input where a user can change it, focus out or press enter. But when you press enter both keydown and blur is triggered, so myFunction() gets triggered twice.

So instead of writing two separate functions for keydown and blur, you can instead put them into a single function:

my_input.on('keydown blur', function (e) {

    // was it the Enter key?
    if (e.which == 13) {
        $(this).blur();
    }

    if (e.type == 'blur') {
        myFunction();
    }

});

I had a similar problem. I'm allowing the user to edit a single field and when they press Enter or move off that field, I send an Ajax request to update it. I found that when I pressed Enter the Ajax request was sent twice.

So rather than calling my request on Enter, I tried calling $input.blur() instead, and that worked! Which got me to thinking... If the Enter key causes a blur do I even need to try to capture it?

In my case, I did not need to. I found that all I needed was the blur because the Enter key triggered it anyway. I'm not sure if that's 100% across all browsers, but I did test on current versions of Chrome, Firefox, IE and Safari, all of which worked fine.

So, I suggest that you either just don't capture the Enter at all, or you simply call blur() to trigger the actions you need.