web-dev-qa-db-ja.com

jQueryの単一のkeypressイベントで複数のキーを検出する

単一のイベントを発生させるためにキープレスの混合を組み合わせることはまったく可能ですか?

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

Chromeで試しましたが、イベントは発生しません。

クレイジーと呼びますが、Chrome拡張機能をプッシュします D+E+V 一緒にキーを押して、非表示の開発者モードにします。

42
remarsh

あなたがそれを検出したい場合 d、 e、そして v キーはすべて同時にダウンしていました。keydownkeyupの両方を監視し、ダウンしているキーのマップを保持する必要があります。それらがすべてダウンしたら、イベントを起動します。

例: ライブコピー | ソース

var map = {68: false, 69: false, 86: false};
$(document).keydown(function(e) {
    if (e.keyCode in map) {
        map[e.keyCode] = true;
        if (map[68] && map[69] && map[86]) {
            // FIRE EVENT
        }
    }
}).keyup(function(e) {
    if (e.keyCode in map) {
        map[e.keyCode] = false;
    }
});

ある時点ですべてが同時にダウンしている限り、どの順序で押し込まれてもかまいません(確実に押すのが苦痛になるため)。

72
T.J. Crowder

ベガに似ていますが、よりシンプルです

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;
});​
18
Parth Thakkar

おそらく、より単純なキーの組み合わせの方が簡単でしょうか?

Shift + Alt + Dのようなものはどうですか? (ほとんどのブラウザーは既にCtrl + Dを何らかの方法で解釈しているため、おそらくControlキーを使用しないでください)

このコードは次のようになります。

if(e.shiftKey && e.altKey && e.keyCode == 68)
{
  alert('l33t!');
}
8
gplumb

T.J。Crowderからの回答があります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;
    }
});
3
Smelino

3つの主要なイベントを個別にキャプチャし、3番目のイベントの後にのみアクションを起動する必要があります。

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...');
    }
});​

もちろん、これを行う方法はいくつかあります。この例では、キーを同時に押す必要はなく、順番に入力するだけです。 dev

これを使用した場合、一定の時間間隔を置いてpressedフラグをクリアするように拡張することができます。

実施例 です。


免責事項:私は、キーが「一緒に押される」べきであると言った元の質問に気付きます。他の回答者は、一緒に押されるキーに十分なソリューションをすでに提供しているため、これは単なる代替です。

1
FishBasketGordo

(この投稿の時点で)3つのトップアンサーを試しましたが、どれもうまくいきませんでした。 キーをリセットしませんでした

3つのキーが必要な場合、スクリプトを1回起動した後に起動します。3つのキーのいずれかを押すと、再び起動します。

このスクリプトを書いたばかりで、非常にうまく機能しています。 Shift + Sを使用して発砲しますが、簡単に変更できます。組み合わせを押すとリセットされます。

var saveArray = new Array();
saveArray[0] = false;
saveArray[1] = false;

$(document).ready(function(){

    $(document).keydown(function (f){
        if (f.keyCode == 16) {
            saveArray[0] = true;
        }
    });

    $(document).keyup(function (g){
        if(g.which == 16){
            saveArray[0] = false;
        }
    });

    $(document).keydown(function (h){
        if (h.keyCode == 83) {
            saveArray[1] = true;
            if(saveArray[0] == true && saveArray[1] == true){
                saveArray[0] = false;
                saveArray[1] = false;
                keypressSaveFunction();
            }
        }
    });

    $(document).keyup(function (i){
        if (i.which == 83) {
            saveArray[1] = false;
        }
    });
});

    function keypressSaveFunction(){
        alert("You pressed Shift+S");
    }

フィドル: http://jsfiddle.net/9m8yswwo/13/

1
Nemo-Omen

もう少し最新のソリューションは、 矢印関数 および 残りのパラメーター を利用しています。

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>

私がよく理解している場合:例フィドル、 http://jsfiddle.net/gAtTk/ (jsコンソールを見てください)

このコードにより、単語「dev」を入力できます(この例では、最後にイベントkeyupが削除されます)

(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()));
0
fcalderan

「同時に」複数のキーを処理するには、keydownイベントとkeyupイベントを使用する必要があります。

input.on("keydown", function (e) {
                        if (e.which == 17) {
                            isCtrl = true; // Ctrl
                            return;
                        }

                        /* Ctrl and "c" */
                        if (isCtrl && e.which == 67) {
                            //some code 
                        }
                    }).keyup(function (e) {
                        if (e.which == 17) {
                            isCtrl = false; // no Ctrl
                        }
                    });
0
kapsiR

このコードを使用して、複数のキーを押してイベントをトリガーし、タイプミスを防ぐために100ミリ秒後にタイムアウトします。この例では、100msの期間内にA、Z、Eが押されると、イベントがトリガーされます。

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);
});
0