简体   繁体   中英

How to track a series of key presses in JavaScript?

I'm extremely new to JavaScript and don't know where I'm going wrong. I would like to make a function that executes after a correct series of keyEvents. Essentially, when a user presses keys , "j", "a", "c", "o", and "b" in this order (and this order only) an element on my web Page will become visible. This element is currently hidden using a CSS style tag: <div id="hideaway" style="display:none;">

 <script> function keyListener(event) { event = event || window.event; //capture the event, and ensure we have an event var key = event.key || event.which || event.keyCode; //find the key that was pressed if(key==106) { //this is for 'j' document.getElementById("hideaway").style.display="block"; event = event || window.event; //capture the event, and ensure we have an event var key = event.key || event.which || event.keyCode; //find the key that was pressed if(key==97) { //this is for 'a' event = event || window.event; //capture the event, and ensure we have an event var key = event.key || event.which || event.keyCode; //find the key that was pressed if(key==99) { //this is for 'c' event = event || window.event; //capture the event, and ensure we have an event var key = event.key || event.which || event.keyCode; //find the key that was pressed if(key==111) { //this is for 'o' event = event || window.event; //capture the event, and ensure we have an event var key = event.key || event.which || event.keyCode; //find the key that was pressed if(key==98) { //this is for 'b' event = event || window.event; //capture the event, and ensure we have an event var key = event.key || event.which || event.keyCode; //find the key that was pressed document.getElementById('hideaway').style.display='block'; } } } } } } document.getElementById("hideaway").addEventListener("keydown", keyListener); </script> 

All comments are appreciated.

I implemented a Konami code easter egg like this:

var code = "";
window.addEventListener("keydown",function(e) {
    code = (code+String.fromCharCode(e.keyCode || e.which)).substr(-11);
    if( code == "&&((%'%'BA ") {
        window.removeEventListener("keydown",arguments.callee);
        // do stuff here
    }
},false);

The important things here are:

  • .substr(-11) trims the input sequence to 11 characters - in your case, you'll want -5 , the length of "jacob"
  • Letters are uppercase. You should check for JACOB
  • In the above, the code uses the corresponding characters for the keycode values for the arrow keys. In your case, you just need the letters, so don't worry about those.

one way of doing it:

http://codepen.io/christianpugliese/pen/GpKJXN

var PASSCODE = ['j','a','c','o','b'],
    current = 0,
    logger = document.getElementById('logger');

function keyListener(e) {
    var code = e.keyCode || e.which,
      str = String.fromCharCode(code);

    if(str === PASSCODE[current]){
        current++;
        logger.innerHTML += str;
        console.log(current, PASSCODE.length);
        if(current >= PASSCODE.length){
          console.log('voi la');
        }
  } else {
      current = 0;
      logger.innerHTML = '';
  }

}

document.addEventListener("keypress", keyListener);

In answer to why it didn't work.

  1. Browser javascript is event driven. A keydown listener function will get called at the start of each key press. So each code repetition of

     event = event || window.event; //capture the event, and ensure we have an event var key = event.key || event.which || event.keyCode; //find the key that was pressed 

is not waiting for a new key down event but simply accessing values associated with the current key press multiple times. To fix this the handler has to remember the state of how many characters have been matched in previous events before taking action.

  1. Registering a non capturing event listener on a hidden block is unlikely to get executed: the block cannot be the target of an event nor receive events bubbling up from child elements. The solution to this is either to register the listener globally or perhaps use event capture (the 3rd parameter of addEventListener).

A worked example to illustrate these points follows. If unfamiliar with them please read up on object literals and the Function.prototype.bind method. The example also waits for page load before doing anything.

<!DOCTYPE html><html><head><title>EasterEgg</title><meta charset="utf-8">
<script>

var easterEgg = 
{ str: "jacob",
  length: 5,
  got: 0,
  blockId: "hideaway",

  test: function(event)
  {  event = event || window.event;
     var c = event.key;
     if(!c) // legacy method
     {  var keyCode = event.keyCode || event.which;
        c = String.fromCharCode(keyCode);
     }
     if( c.toLowerCase() != this.str.charAt(this.got))
        this.got = 0;  // start again
     else
        if(  ++this.got == this.length)
        {   document.getElementById(this.blockId).style.display="block";
            window.removeEventListener("keydown", this.test, false);
        };
     return true;
  },
}
easterEgg.test = easterEgg.test.bind(easterEgg);

window.addEventListener("load", function()
   { window.addEventListener("keydown", easterEgg.test, false);
   }, false);

</script>
</head>
<body><header>Hello</header>
  <div id="hideaway" style="display:none"> SURPRISE! </div>
</body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM