3


I am handling two events, both focusout and keydown, in a $(elementID).on() event-handler.

Calling $(elementID).off("focusout keydown"); as the last line within the .on() event-handler seems to be partially working  --  focusout is working correctly, but keydown is firing twice.


Edit:   With @Barmar's findings, keydown is first triggering focusout and then keydown. This is happening in Firefox 22, but apparently not in Chrome 29.


Here is the HTML:
<input type = "text" id = "textField" />
<input type = "button" onclick = "setFocus();" value = "click here" />

<ol>
      <li>Type some text into the textfield.</li>
      <li>Click the button.</li>
      <li>
            Click out of the textfield, or
            <br />
            <i>press enter for some weird behavior.</i>
      </li>
</ol>


...here is the javascript / jQuery:

 function setFocus() {
       $("#textField").focus();
       $("#textField").select();

       var count = 1;
       $("#textField").on("focusout keydown", function(e) {

              // if clicked away, or the enter key is pressed:
              if (e.type == "focusout" || e.keyCode == 13) {
                     alert(e.type + ": " + count++);
              }

              // this doesn't seem to be working correctly:
              $("#textField").off("focusout keydown");
       });
 }


...and here is the jsFiddle.

Ian Campbell
  • 2,678
  • 10
  • 56
  • 104

5 Answers5

5

From what i can deduce, that when you press enter keydown event is triggered alert for keydown opens and then focusout is triggered coz of enter default functionality then alert for focusout. So what you have to do is unbind the focusout if enter is pressed

    $("#textField").on("focusout keydown", function (e) {
        if (e.type == "focusout" || e.keyCode == 13) {
           if(e.keyCode == 13){
             $(this).unbind('focusout');
           }
        alert(e.type + ": " + count++);
        }
    $("#textField").off("focusout keydown");
    });

Here is the edited JsFiddle

Sathya Raj
  • 1,079
  • 2
  • 12
  • 30
0

have you tried using the one event binding instead of on ? then you wouldnt have to unbind at the end.

  $("#textField").one("focusout keydown", function(e) {

          // if clicked away, or the enter key is pressed:
          if (e.type == "focusout" || e.keyCode == 13) {
                 alert(count++);
          }
   });

http://jsfiddle.net/yaFeF/12/

mkoryak
  • 57,086
  • 61
  • 201
  • 257
0


Ok, so here is a nasty hack:

function setFocus() {
    $("#textField").focus();
    $("#textField").select();

    var count = 1;

    // when clicking away:
    $("#textField").on("focusout keydown", function(e) {
        var code = e.keyCode ? e.keyCode : e.which;

        // if the key is NOT the enter or tab keys, which also trigger focusout:
        if (code !== 13 && code !== 9) {
            alert(e.type + ": " + count++);
        }

        $("#textField").off("focusout keydown");
    });

    // when hitting enter, or tabbing away:
    $("#textField").on("keydown", function (e) {
        var code = e.keyCode ? e.keyCode : e.which;

        // if the key pressed is the enter or tab key:
        if (code === 13 || code === 9) {
            alert(e.type + ": " + count++);
        }

        $("#textField").off("keydown");
    });
}


...and the jsFiddle.



I don't consider this a viable solution though, because this leads to unnecessary code duplication and is difficult to understand.

It seems as if focusout and keydown are inseparable... So handling both simultaneously and checking that code !== 13 first, then handling only keydown and checking that code === 13 will separate the events.

However, now the Tab key has to be handled too, ack! So, I have congruently included checks for code !== 9 and code === 9 as well.
Ian Campbell
  • 2,678
  • 10
  • 56
  • 104
0
$('Selector')
.on('keydown',function(e){
    if (13 == e.which) {
       // do somthing who lead 'focusout' like $('Somthing-else').click()
        $(this).unbind('focusout');
    }
})
.on('focusout', function(e){
    $('Somthing-else').click()
})
Jon
  • 1
-1

you have inline event.. setFocus(); that was called when button is clicked. remove inline event and change your script to this

$(document).ready(function(e) {
    var count= 1;
    $("#textField").on("focusout keydown", function(e) {
        if (e.type == "focusout" || e.keyCode == 13) {
            alert(count++);
        }
    });
});
kashimu
  • 174
  • 2
  • 9
  • He wants you to have to click on the button to enable the other event handlers. – Barmar Jul 30 '13 at 01:53
  • he wants? oh! sorry i dont see exactly that he wants to set that event on the button.. i see that his problem is some weird events that he wants to avoid – kashimu Jul 30 '13 at 01:58
  • Read the instructions in the text, it says to type some text, then click on the button, then press Enter to see the problem. Clicking on the button adds the event handler that has the problem. Anyway, I'll bet your code has the same problem of firing multiple events. – Barmar Jul 30 '13 at 01:59
  • See http://jsfiddle.net/yaFeF/26/. This is your code, and it has the same problem when you press Enter. – Barmar Jul 30 '13 at 02:03