Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

the shift key is just ignored after another key has been depressed, poor shift key. How do I detect when it is released?

I have a text input, that presently goes transparent when a user presses shift (keydown) and binds a listener for the shift key going up

ie.

$('#foo').keydown(function(){
      if(event.which==16){
          //make #foo transparent
          $(this).keyup(function(){
              if(event.which==16){
                 //return #foo to its former glory
                 $(this).unbind('keyup');
              }
          });
       };
  })

This works fine when no characters are pressed in the interim between depressing and releasing the shift key. The problem is that when shift is down and another character is pressed, the shift key seems to have been completely forgotten about. When the shift key is released, no keyup fires.

I tried triggering a 'fake' keydown with the .which property set to 16, to nudge it in the right direction after other characters are pressed, but to no avail.

Any suggestions would be greatly appreciated!

like image 673
Justin Avatar asked Jul 03 '13 11:07

Justin


1 Answers

While pressing shift, it will continuously trigger keydown events until you release it, so your example will bind as many keyup handlers as there are keydown events triggered. This will most likely cause all kind of weird problems.

Instead, bind both keydown and keyup to the same handler and do your magic in there:

$("#foo").on("keydown keyup", function (e) {
    if (e.which === 16) {
        if (e.type === "keydown") {
            // make #foo transparent
        } else {
            // return #foo to its former glory
        }
    }
});

See test case on jsFiddle.

However, if you lose focus of the input while pressing shift and then release, it will not work as expected. One way to solve it is to bind to window instead:

var $foo = $("#foo");
var shiftPressed = false;

$(window).on("keydown keyup", function (e) {
    if (e.which === 16) {
        shiftPressed = e.type === "keydown";
        if (shiftPressed && e.target === $foo[0]) {
            $foo.addClass("transparent");
        } else {
            $foo.removeClass("transparent");
        }
    }
});

$foo.on("focus blur", function (e) {
    if (e.type === "focus" && shiftPressed) {
        $foo.addClass("transparent");
    } else {
        $foo.removeClass("transparent");
    }
});

See test case on jsFiddle.

like image 191
mekwall Avatar answered Sep 28 '22 08:09

mekwall