views:

472

answers:

5

I would like to be able to log the key presses on a specific page, trying to implement an 'Easter egg' type functionality where when the correct keys are pressed in the correct order it triggers and event.

Can anyone give me any pointers?

A: 

I have earlier used this code to use the up/down arrows to scroll through a list, it should be relativly easy to extend this to check for a certain key combo.

$("#SearchInput").keydown(function(e){
  switch(e.which) { 
     // User pressed "up" arrow
     case 38:
        navigate('up');
     break;
     // User pressed "down" arrow
     case 40:
        navigate('down');
     break;
     // User pressed "enter"
     case 13:
        if(currentUrl != '') {
           window.location = currentUrl;
        }
     break;
  }
Hans Skov
A: 

Using jQuery:

$(document).keyup( function(e) {
    if (e.keyCode == 27) {
        alert("You pressed escape");
    }
});

This captures key presses on the whole page not just a specific element.

This blog post details how to capture CTRL+Key shortcuts.

Greg K
+2  A: 

I'm not sure of the exact keypress codes, I borrowed from Hans Kov's answer. I would use an array like a stack and just push a new keypress onto the stack, then pop them off to check for correct order.

<script type="text/javascript>

var keypresses = [];
  $(document).ready(function() {
    body.bind('keypress', function(event) {
      switch(event.keyCode) {
        case 40:
          keypresses.push('down');
        break;
        case 38:
          keypresses.push('up');
      }

      checkForEasterEgg(keypresses);
    });
  });

  function checkForEasterEgg(keyArray) {
    var length = keyArray.length;
    for(var i = 0; i < length; i++) {
      // using keyArray.pop(), check if order matches up up down down left right left right b a
      if (easterEggPassed) {
        console.log('30 lives, woohoo!');
      }
    }
  }
</script>
Hooray Im Helping
Nice answer. Although, I always find drect use of literals (e.g.40, 38) is better replaced by some sort of constant/object literal as per my answer below.
James Wiseman
@James, agreed, I upvoted your answer for that reason.
Hooray Im Helping
+3  A: 

In such circumstances it might also be useful to be able to check for the ctl/alt/shift keys:

if (e.altKey) {
}

if (e.ctrlKey) {
}

if (e.shiftKey) {
}

For keypress codes, the following object literal should help:

var Key =
{
    BACKSPACE: 8,
    TAB: 9,
    ENTER: 13,
    ESC: 27,
    PAGEUP: 33,
    PAGEDOWN: 34,
    END: 35,
    HOME: 36,
    LEFT: 37,
    UP: 38,
    RIGHT: 39,
    DOWN: 40,
    HELP: 47,
    H: 72,
    K: 75,
    N: 78,
    R: 82,
    NUMERIC_PLUS: 107,
    F1: 112,
    F2: 113,
    F3: 114,
    F4: 115,
    F5: 116,
    F6: 117,
    F7: 118,
    F8: 119,
    F9: 120,
    F10: 121,
    F11: 122,
    F12: 123,
    PLUS: 187,
    MINUS: 189,
    V: 86
}

So instead of:

  switch(event.keyCode) { 
    case 40: 
      keypresses.push('down'); 
    break; 
    case 38: 
      keypresses.push('up'); 
  } 

We can say:

switch(event.keyCode) { 
    case Key.DOWN: 
        keypresses.push('down'); 
        break; 
    case Key.UP: 
        keypresses.push('up'); 
        break; 
} 

This promotes self documenting code, and is more readable and maintainable.

James Wiseman
+6  A: 

Well, even though another answer has been accepted, I'm going to throw one out there anyway.

$(document).ready(function() {

    var easterEgg = 'egg';
    var eggLength = easterEgg.length;
    var keyHistory = '';
    var match;
        $(document).keypress(function(e) {
            keyHistory += String.fromCharCode(e.which)
            match = keyHistory.match(easterEgg); 
            if(match) {
                alert(match);
                keyHistory = match =  '';
            } else if (keyHistory.length > 30) {
                keyHistory = keyHistory.substr((keyHistory.length - eggLength - 1));
            }
        });
});

When you ultimately type 'egg' (for this example), you will get an alert, and the key history will reset.

EDIT: Updated the code to truncate the string if it gets too long.

patrick dw
More elegant so have adjusted my answer.
danit