web-dev-qa-db-ja.com

キーがダウンしているかどうかを確認しますか?

JavaScriptでキーが現在ダウンしているかどうかを検出する方法はありますか?

「キーダウン」イベントについては知っていますが、必要なものではありません。キーが押されてからしばらくして、まだ押されているかどうかを検出できるようにしたいと思います。

追伸:最大の問題は、一定期間後、キーが繰り返され、悪魔のようなキーダウンおよびキーアップイベントが発生することです。単純なisKeyDown(key)関数があればいいのですが、そうでない場合は、この問題を克服/回避する必要があります。

81
Daniel X Moore

JavaScriptでキーが現在ダウンしているかどうかを検出する方法はありますか?

いや。唯一の可能性は、各keyupkeydownを監視し、記憶することです。

しばらくすると、キーが繰り返され、悪魔のようなキーダウンイベントとキーアップイベントが発生します。

すべきではありません。間違いなくkeypressが繰り返され、多くのブラウザーではkeydownが繰り返されますが、keyupが繰り返される場合はバグです。

残念ながら、これは完全に前代未聞のバグではありません。Linux、Chromium、Firefox(GTK +で実行されている場合、Ubuntuなどの一般的なディストリビューションにあります)は、どちらも保持されたキーに対して繰り返しkeyup-keypress-keydownシーケンスを生成し、キーを非常に速く叩いている人と区別することは不可能です。

62
bobince

keyupリスナーとkeydownリスナーを使用して、キーがいつダウンおよびバックアップするかを追跡することに加えて、実際にはare特定のキーがダウンしたかどうかを示すいくつかのプロパティがあります。

_window.onmousemove = function (e) {
  if (!e) e = window.event;
  if (e.shiftKey) {/*shift is down*/}
  if (e.altKey) {/*alt is down*/}
  if (e.ctrlKey) {/*ctrl is down*/}
  if (e.metaKey) {/*cmd is down*/}
}
_

これは、keydownkeyup、およびkeypressからのものなど、ブラウザで生成されたすべてのイベントオブジェクトで使用できるため、mousemoveを使用する必要はありません。

document.createEvent('KeyboardEvent')およびdocument.createEvent('KeyboardEvent')を使用して独自のイベントオブジェクトを生成し、_e.shiftKey_などを探してみましたが、運がありませんでした。

私はChrome 17を使用しています

121
Devin G Rhode

私の解決策:

var keys = {};
window.onkeyup = function(e) { keys[e.keyCode] = false; }
window.onkeydown = function(e) { keys[e.keyCode] = true; }

スクリプト内のどこかでキーが押されているかどうかを確認できます

keys["code of the key"]

正しい場合、キーが押されます。

35
Robert

IsKeyDown関数のようなものはないと思いますが、独自の関数を作成することもできます。

基本的に、監視するキーの数を長さとする配列を作成します。次に、documents/pages/controls keyUpおよびkeyDownイベントを使用して、そのキーの状態で配列を更新します。

次に、特定のキーがダウンしているかどうかを確認し、ブール値を返す関数を作成します。

var keyEnum = { W_Key:0, A_Key:1, S_Key:2, D_Key:3 };
var keyArray = new Array(4);

function onKeyDown()
{
    // Detect which key was pressed
    if( key == 'w' )
        keyArray[keyEnum.W_Key] = true;
    // Repeat for each key you care about...
}

function onKeyUp()
{
    // Detect which key was released
    if( key == 'w' )
        keyArray[keyEnum.W_Key] = false;
    // Repeat for each key you care about...
}

function isKeyDown(key)
{
    return keyArray[key];
}

それはあなたが望むものを達成する必要があります。

11
FallenAvatar
/*
Tracks what keys are currently down on the keyboard
*/

function keyboard_module(onUpdate){
    var kb = {};
    var unicode_mapping = {};
    document.onkeydown = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        kb[key] = true;
        if(onUpdate){
            onUpdate(kb);
        }
    }

    document.onkeyup = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        delete kb[key];
        if(onUpdate){
            onUpdate(kb);
        }
    }

    function getKey(unicode){
        if(unicode_mapping[unicode]){
            var key = unicode_mapping[unicode];
        }else{
            var key= unicode_mapping[unicode] = String.fromCharCode(unicode);
        }
        return key;
    }
    return kb;
}

function testing(kb){
    console.log('These are the down keys', kb);
}


var keyboard = keyboard_module(testing);

....
//somewhere else in the code
if(keyboard['K']){/*do something special */}
1
RobKohr

他の人々は以前にこの種の質問をしたことがあります(ただし、ここには明らかなだましは見当たりませんが)。

答えは、keydownイベント(およびそのツインkeyup)がすべての情報であると思います。繰り返しはオペレーティングシステムにしっかりと接続されており、アプリケーションプログラムは、キーの実際の状態をBIOSに照会する機会をあまり得られません。

あなたができること、そしておそらくあなたがこれを機能させるために必要なのは、プログラムでキーのバウンスを解除することです。基本的に、keydownkeyupを自分で評価できますが、最後のkeyup...の後にあまりにも早く発生する場合はkeydowneventを無視できます。 keyupへの応答を遅らせて、0.25秒のkeydownのような後続のkeyupイベントがないことを確認します。

これには、タイマーアクティビティの使用、および以前のイベントのミリ秒時間の記録が含まれます。非常に魅力的なソリューションとは言えませんが、...

1
Carl Smotricz

ブラウザーに既にビルトインされているものがあるかどうかを確認するためにここに行きましたが、そうではないようです。これは私のソリューションです(ロバートの答えに非常に似ています):

_"use strict";

let is_key_down = (() => {
    let state = {};

    window.addEventListener('keyup', (e) => state[e.key] = false);
    window.addEventListener('keydown', (e) => state[e.key] = true);

    return (key) => state.hasOwnProperty(key) && state[key] || false;
})();
_

次に、is_key_down('ArrowLeft')を使用してキーが押されたかどうかを確認できます。

1
antonagestam

次のコードは私が使用しているものです:

var altKeyDownCount = 0;
window.onkeydown = function (e) {
    if (!e) e = window.event;
    if (e.altKey) {
        altKeyDownCount++;
        if (30 < altKeyDownCount) {
            $('.key').removeClass('hidden');
            altKeyDownCount = 0;
        }
        return false;
    }
}

window.onkeyup = function (e) {
    if (!e) e = window.event;
    altKeyDownCount = 0;
    $('.key').addClass('hidden');
}

ユーザーがしばらく(約2秒)Altキーを押し続けると、ラベルのグループ(class = 'key hidden')が表示されます。 Altキーを離すと、ラベルが消えます。 jQueryとBootstrapの両方が使用されます。

1
Johnny

this answerを見て、onkeyuponkeydownを使用します。 ここ は、それらのイベントに関するより具体的な情報です。

0
Claudiu

上記の回答をスキャンしたところ、提案されたkeydown/keyupアプローチは特別な状況下でのみ機能します。ユーザーがAltキーを押しながらタブを離れるか、キージェスチャを使用して新しいブラウザーウィンドウまたはタブを開くと、keydownが登録されます。これは、その時点ではキーがどうかを判断できないためです。 Webアプリが監視しているもの、または標準のブラウザーまたはOSショートカットです。ブラウザのページに戻ると、キーは保持されていると思われますが、その間にリリースされました。または、ユーザーがマウスで別のタブまたはアプリケーションに切り替えてから、ページの外にリリースされている間、いくつかのキーが単に保持されます。

修飾キー(Shiftなど)は、mousemoveなどを介して監視できます。タブで戻るときに、少なくとも1つのマウス操作が想定されます。これはよくあることです。

他のほとんどのキー(修飾子、TabDeleteを除く、ただしSpaceEnterを含む)の場合、keypressの監視はほとんどのアプリケーション-キーが押されたままになります。ただし、keypress発火の周期性のため、キーのリセットには多少の遅延があります。基本的に、keypressが発火し続けない場合、ほとんどのキーを除外することができます。これは、修飾子と組み合わせてかなり気密性がありますが、TabBackspaceをどう処理するかについては検討していません。

このDOMの弱点を抽象化するライブラリがあるか、またはDOMの標準的な変更がそれを処理してくれると思います。これはかなり古い質問です。

0
Robert Monfera

これは非常に古い質問ですが、DOM APIを使用するときに、キーボードイベントハンドラーの一貫性のない発火を効果的に「パッチ」する非常に軽量な(〜.5Kb)JavaScriptライブラリがあります。

ライブラリは Keydrown です。

以下は、リスナーを設定するキーを変更するだけで、私の目的に適した動作コードのサンプルです。

kd.P.down(function () {
  console.log('The "P" key is being held down!');
});

kd.P.up(function () {
  console.clear();
});

// This update loop is the heartbeat of Keydrown
kd.run(function () {
  kd.tick();
});

私が書いているRed Light Green Lightゲームで適切な一時停止アニメーションを作成するために、Keydrownをクライアント側のJavaScriptに組み込みました。ゲーム全体を表示できます こちら 。 (注:将来これを読んでいる場合、ゲームは完全なコードでプレイできるはずです:-D!)

これがお役に立てば幸いです。

0
buildpax