2012-05-18 7 views
36

単一のイベントを発生させるためにキー押しの組み合わせを組み合わせることは可能ですか?jQueryで単一のキー入力イベントで複数のキーを検出

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

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

は狂気私を呼び出しますが、私はChromeの拡張機能を書いて、隠された開発者モードにそれを強制するために一緒にD + E + Vキーをプッシュするのです。

+0

keyCodeは1つのキーのみを表すことができます。これを検出するには、keydown + keyup +フラグの組み合わせを使用してください。 – yent

+0

可能な複製[jQuery .keypress()が複数のキーを同時に検出できるか?](http://stackoverflow.com/questions/4954403/can-jquery-keypress-detect-more-than-one-key -at-the-same-time) –

+0

受け入れられた回答を[this](http://stackoverflow.com/a/35249618/3853934)に変更することを検討してください。それはより現代的かつ一般的なアプローチを提示する。 –

答えて

59

は、あなたが​​とkeyupの両方を見て、もののマップを維持する必要がありますそれはダウンしている。彼らがすべてダウンしたら、あなたのイベントを起こしてください。

例:Live copy | source

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

私はあなたが彼らがいる限り、彼らはいくつかの点で同時にすべてダウンしていると(つまり、確実に押す苦痛だろうと)に押し下げられているものを順番気にしないと仮定します。

+0

mmを投稿したほうがよいでしょう。キーボードショートカットのためには、その順序が重要だと思います.. 'ctrl + v'は' v + ctrl'と同じではありません –

+3

@Vega:魚の別のケトル。 –

+0

@DreamWave:いいえ、 'keyup'ハンドラはフラグをクリアします。 –

1

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フラグをクリアすることができます。

ここにはworking exampleがあります。


免責事項:私は元の質問は、キーが「一緒に押す」されるべきであると述べた実感。これは、他の回答者がすでに一緒に押されているキーのための十分な解決策を提供しているので、単なる代替案である。

+0

私はこれをChromeでテストしましたが、元のキーコードでは機能しませんでした。これまでに私はこれまで走っていましたが、なぜ彼らが違うのか忘れてしまいます。 – FishBasketGordo

0

私はよく理解場合:例のフィドル、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

複数のキーを同時に処理するには、keydownイベントとkeyupイベントを使用する必要があります。あなたはDE、そしてVキーがすべて同時にダウンしたことを検出したい場合は

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

まだ定義されていない変数に値を割り当てることはできません。 –

+0

最初に定義されていない変数は、グローバルスタック上の新しい変数になります。これは、これがどのように可能であるかの一例に過ぎない。 JSFiddleを提供することはできますが、問題は既に解決済みとマークされています... – kapsi

+0

これはバグであり、機能ではなく、グローバル変数も悪いです。 –

18

Vega'sに似ています...簡単です

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

ここでそれをする:http://jsfiddle.net/5QYKH/ –

+4

これは本当に良いですし、うまくいくでしょう。キーのシーケンスと一致する必要がある場合は、配列にプッシュすることで順序を確認することができます: 'down [e.keyCode] = true'の代わりに' down.push(e.keyCode) 'と言って、代わりに検証してください(down [0] === 68 && down [1] === 69 && down [2] === 86)このように:if(down [68] && down [69] && down [86] '。 – lu1s

+2

lu1sのコメントを補うために[fiddle](http://jsfiddle.net/bplumb/B2efC/1/)を作成しました。 –

8

もっと簡単なキーの組み合わせはおそらく簡単でしょうか?

Shift + Alt + Dはどうですか?

このためのコードは、このようなものになるだろう(ほとんどのブラウザは、すでに一つの方法または別でCtrl + Dを解釈するので、あなたはおそらく、Controlキーを使用しないでください):あなたが気にした場合

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

それは質問に対する答えではありませんか? –

+0

@ParthThakkar - 質問から、「非表示の開発者モードにする」という要件を導き出すことができます。実用的であることから、私は同じ最終結果を達成するための簡単な選択肢を提案しました。 – gplumb

+0

大丈夫です...それは行く方法かもしれません...私はそれが必要な質問に対する答えではないと思ったので、いいえ、違反はありません!) –

-1

また、キーを押したまま別のキー(例:Shift + Del、Del、Del ...)を押す必要があります。最初のキーを押し上げなくても、イベントを再開することができます。 @ ParthThakkarの答えに対する@ lu1sのコメントを拡張したBlakePlummの[fiddle]コメント。

また、jQueryの.on()を使用すると、特定の要素のキーシーケンスだけを聞くことができます。 'body'を 'input.selector'などに変更します。

var map = []; 
var down = []; 
$(document).on('keydown','body', function(e) { 
    if(!map[e.which]){ 
     down.push(e.which); 
     if(down[0] === 68 && down[1] === 69 && down[2] === 86) { 
      console.log('D + E + V'); 
     } else if(down[0] === 16 && down[1] === 46) { 
      console.log('SHIFT + DEL'); 
     } 
     /* more conditions here */ 
    } 
    map[e.which] = true; 
}).keyup(function(e) { 
    map[e.which] = false; 

    /* important for detecting repeat presses of 
     last key while holding first key(s) 
     (can be shortened. see fiddle) */ 
    var len = down.length; 
    while (len--) { 
     if(down[len] === e.which) down.splice(len,1); //removes only the keyup'd key 
    }   
    $('.alert').html(''); 
}); 

追加思考: あなただけのちょっと順番を気にしている場合 - つまり、最初のキーはちょうど限り、あなたのメインイベント、発射キーがCTRL +シフトのような最後の(もの押されるように、ダウンする必要がありますより多くの栄光のオプションとライブデモで

else if(down.length>2) { 
    if($.inArray(68,down)!=-1 && $.inArray(69,down)!=-1 && down[2] === 86) { 
     $('.alert').html('A hacky D+E+V was pressed'); 
    } 
} 

フィドル:+ TAB、TAB、TAB)、この条件を追加 - http://jsfiddle.net/kstarr/4ftL1p3k/

-1

https://github.com/JesseBuesking/jquery.hotkeys.extended

これをチェックしてください。あなたはこれを探しているかもしれません。

複数のキーを押して機能を起動できます。 例:p + t + k

$(document).hotkeys('p', 't', 'k', function(){ 
     //show blurbox 
     $('#popup').blurbox({ 
      blur: 10, animateBlur: true, bgColor: 'rgba(255,255,0,0.2)' 
     })bb.show(); 
    }); 

おそらく、これを探しています。

1

私は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/

+0

これは、ユーザはShiftキーを押し続けて、もう一度Sを押します。 Sのkeydownイベント(Shiftキーが離されたと仮定して)で 'saveArray [0] = false'を強制すると、かなり恐ろしいハックです。一方、それはあなたのために働いた理由かもしれません。 – poshest

+0

* 'new Array()'を使ってはいけません。 –

0

もう少し現代的な解決策は、arrow functionsrest 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>

0

複数によってトリガイベントを持つように、このコードを使用しますミスタイプを防ぐために100ms後にキーを押す+タイムアウト。 この例では、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); 
}); 
関連する問題