Detect multiple keys on single keypress event in j

2019-01-01 13:32发布

Is it at all possible to combine a mixture of keypress' to fire a single event?

$(document).keyup(function(e){
    if (e.keyCode == 68 && e.keyCode == 69 && e.keyCode == 86) {
        alert('oh hai');
    }
});

I've tried it in Chrome but the event doesn't fire.

Call me crazy but I am writing a Chrome extension and want to push D+E+V keys together to force it into a hidden developer mode.

12条回答
看淡一切
2楼-- · 2019-01-01 13:40

Use this code to have an event triggered by multiple key presses + Timeout after 100ms to prevent mistypes. In this example : if A,Z,E are pressed within a time period of 100ms, the event will be triggered.

var map = {65:false,90:false,69:false}; //Modify keyCodes here
$(document).keydown(function(e){
    console.log(e.keyCode);
    map[e.keyCode] = e.keyCode in map ? true : map[e.keyCode] || false;
    var result = Object.keys(map).filter(function(key){
        return map[key];
    }).length === Object.keys(map).length ? true : false;
    if(result){
        //Your event here
        Object.keys(map).forEach(function(key){
            map[key] = false;
        });
    }
    setTimeout(function(){
        map[e.keyCode] = false;
    },100);
});
查看更多
刘海飞了
3楼-- · 2019-01-01 13:42

I have answer from T.J. Crowder in plain javascript for someone who would want to avoid Jquery.

//A W S D simultaneously
var map = {65: false, 87: false, 83: false, 68: false};
document.body.addEventListener('keydown', function (e) {
    var e = e || event; //to deal with old IE
    if (e.keyCode in map) {
        map[e.keyCode] = true;
        if (map[65] && map[87]) {
            console.log('up left');
        }else if (map[83] && map[68]) {
            console.log('down right');
        }else if (map[87] && map[68]) {
            console.log('up right');
        }else if (map[83] && map[65]) {
            console.log('down left');
        }
    }
});
document.body.addEventListener('keyup', function (e) {
    if (e.keyCode in map) {
        map[e.keyCode] = false;
    }
});
查看更多
不再属于我。
4楼-- · 2019-01-01 13:42

You would need to capture the three key events separately and fire your action only after the third one.

var keys = {
        d: { code: 100, pressed: false, next: 'e' },
        e: { code: 101, pressed: false, next: 'v' },
        v: { code: 118, pressed: false, next: 'd' }
    },
    nextKey = 'd';

$(document).keypress(function(e) {
    if (e.keyCode === keys[nextKey].code) {
        keys[nextKey].pressed = true;
        nextKey = keys[nextKey].next;
    } else {
        keys.d.pressed = false;
        keys.e.pressed = false;
        keys.v.pressed = false;
        nextKey = 'd';
    }

    if (keys.d.pressed && keys.e.pressed && keys.v.pressed) {
        alert('Entering dev mode...');
    }
});​

There's a number of ways to do this of course. This example doesn't require you to hold the keys down simultaneously, just that you type them in order: d e v.

If you used this, you might want to augment it to clear the pressed flags after some time interval.

Here's a working example.


Disclaimer: I realize the original question said that the keys should be "pressed together". This is just an alternative as other answerers have already provided sufficient solutions for the keys being pressed together.

查看更多
旧人旧事旧时光
5楼-- · 2019-01-01 13:50

Similar to Vega's...but simpler

var down = {};
$(document).keydown(function(e) {
    down[e.keyCode] = true;
}).keyup(function(e) {
    if (down[68] && down[69] && down[86]) {
        alert('oh hai');
    }
    down[e.keyCode] = false;
});​
查看更多
若你有天会懂
6楼-- · 2019-01-01 13:52

A bit more modern solution, takes advantage of arrow functions and rest parameters:

const multipleKeypress = (function($document) {
  // Map of keys which are currently down.
  const keymap = {}
  // Update keymap on keydown and keyup events.
  $document.on(
    "keydown keyup"
    // If the key is down, assign true to the corresponding
    // propery of keymap, otherwise assign false.
   ,event => keymap[event.keyCode] = event.type === "keydown"
  )
  // The actual function.
  // Takes listener as the first argument,
  // rest of the arguments are key codes.
  return (listener, ...keys) =>
    $document.keydown(() => {
      // Check if every of the specified keys is down.
      if (keys.every(key => keymap[key]))
        listener(event)
    })
// Pass a jQuery document object to cache it.
}($(document)))

// Example usage:
multipleKeypress(() => console.log("pressed"), 68, 69, 86)

// Automatically focus the snippet result
window.focus()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Try pressing <kbd>d</kbd>, <kbd>e</kbd> and <kbd>v</kbd> at once.</p>

查看更多
旧时光的记忆
7楼-- · 2019-01-01 13:53

if I well understood : example fiddle, http://jsfiddle.net/gAtTk/ (look at your js console)

this code will let you enter the word "dev" (and in this example, at the end the event keyup is removed)

(function(seq) {
    var tmp = seq.slice();
    $(document).on("keyup.entersequence", function(e){
        if (!(e.keyCode === tmp.pop())) {
           tmp = seq.slice();
        }
        else {
           console.log(e.keyCode);  
            if (!tmp.length) {
               console.log('end');
               $(document).off("keyup.entersequence");
            }
        }
    });
}([68,69,86].reverse()));
查看更多
登录 后发表回答