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

19,715

Solution 1

I Couldn't alter class attribute so i'd ended up with,

$(".textbox").on("blur",function () { 
    if($(this).attr('flag')!='1') 
        alert("blur Event fired");
});

$(".textbox").on("keyup",function (event) { 
    $(this).attr('flag','1');
    if(event.keyCode == 13){ // Detect Enter
        alert("KeyUp fired after pressing Enter");
    }
    $(this).attr('flag','0');
});

Solution 2

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!

Solution 3

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.

Solution 4

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();
    }

});
Share:
19,715

Related videos on Youtube

Bhavesh G
Author by

Bhavesh G

Over 10+ years of extensive experience in full-stack web development. Technologies include PHP (5.6, 7, CodeIgniter, Zend Framework, Custom Frameworks), HTML(5), CSS(3), MySQL, SQL, Javascript, web services, SOAP and REST API development jquery, Bootstrap, GIT, LAMP/Apache/NGINX Environment, Linux, MVC methodology, Object-Oriented design, UX and UI responsive design, making functional specs, application design, and architecture, Over 1-4 years of experience in: Amazon AWS / Azure / Heroku cloud, Node.JS, C#, Python, Redis, Memcached, WebRTC, integration, highly adaptive to latest tools and technologies Great at debugging/troubleshooting code, having best practices in coding and software engineering, Agile Development environment

Updated on September 15, 2022

Comments

  • Bhavesh G
    Bhavesh G over 1 year

    After pressing enter I would like that only the keyup event be fired but blur is fired first. How to cancel blur when keyup is fired with enter?

    Please don't suggest to bind both blur and keyup into a single live() method.

    $(".textbox").on("blur",function () { 
        alert("blur Event fired");
    });
    
    $(".textbox").on("keyup",function (event) { 
        if(event.keyCode == 13){ // Detect Enter
            alert("KeyUp fired after pressing Enter");
        }
    });
    
    • Félix Adriyel Gagnon-Grenier
      Félix Adriyel Gagnon-Grenier almost 10 years
      Hey, this is a pertinent question. Please reopen it. It is a real problem I just got, having to get keyup to work before blur.
  • Bhavesh G
    Bhavesh G almost 12 years
    but the question is can i cancel that blur event firing after Pressing Enter ?
  • Chris Baker
    Chris Baker almost 12 years
    See edit. Since blur does not receive any keyboard information, you wouldn't be able to detect what key was involved. Indeed, they key is not the reason the element lost focus, it's the alert that's doing it.
  • Chris Baker
    Chris Baker almost 12 years
    That would work once, and only once, and pollutes the global scope. Bad practice.
  • bstenm
    bstenm almost 12 years
    'That would work once, and only once': well, that really depends on how you organise your whole code; 'pollutes the global scope' : same; ok that's a fairly cheap way indeed but then he's looking for a solution; your solution use the dom for data, that's also bad practice.
  • Chris Baker
    Chris Baker almost 12 years
    [citation needed] -- adding a class to a dom element is not bad practice.
  • bstenm
    bstenm almost 12 years
    Chris, if it is just for the sake of remembering a state, it is. I would try to avoid interacting with the dom just for that, that's not its job. And using a variable inside document.ready is not the global scope ;). You see, I won't let go :D !
  • Chris Baker
    Chris Baker almost 12 years
    Again, [citation needed]. Despite not letting go, the fact remains that the code in your answer never resets the triggerBlur variable to true, so it only works once -- this is not a functional solution. My solution, in addition to working more than one time, is also able to cope with more than one form element on the page. In this, your code also fails to perform. I hope you realize that no amount of commentary or debate will improve the code in this answer, and that it is not a contest. Code either works, or it does not; this code does not, mine does. We're dealing with facts here.
  • osullic
    osullic over 3 years
    good solution. For me, pressing Enter doesn't automatically fire a blur event from the input box I'm dealing with. So I have to capture the keydown event, and if it's 13, I manually fire a blur. Maybe because my input box is not inside a <form> element. I'm not sure, but it's just a heads-up to watch out that the blur event doesn't seem to always fire.