JavaScriptでキーが現在ダウンしているかどうかを検出する方法はありますか?
「キーダウン」イベントについては知っていますが、必要なものではありません。キーが押されてからしばらくして、まだ押されているかどうかを検出できるようにしたいと思います。
追伸:最大の問題は、一定期間後、キーが繰り返され、悪魔のようなキーダウンおよびキーアップイベントが発生することです。単純なisKeyDown(key)関数があればいいのですが、そうでない場合は、この問題を克服/回避する必要があります。
JavaScriptでキーが現在ダウンしているかどうかを検出する方法はありますか?
いや。唯一の可能性は、各keyup
とkeydown
を監視し、記憶することです。
しばらくすると、キーが繰り返され、悪魔のようなキーダウンイベントとキーアップイベントが発生します。
すべきではありません。間違いなくkeypress
が繰り返され、多くのブラウザーではkeydown
が繰り返されますが、keyup
が繰り返される場合はバグです。
残念ながら、これは完全に前代未聞のバグではありません。Linux、Chromium、Firefox(GTK +で実行されている場合、Ubuntuなどの一般的なディストリビューションにあります)は、どちらも保持されたキーに対して繰り返しkeyup-keypress-keydownシーケンスを生成し、キーを非常に速く叩いている人と区別することは不可能です。
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*/}
}
_
これは、keydown
、keyup
、およびkeypress
からのものなど、ブラウザで生成されたすべてのイベントオブジェクトで使用できるため、mousemoveを使用する必要はありません。
document.createEvent('KeyboardEvent')
およびdocument.createEvent('KeyboardEvent')
を使用して独自のイベントオブジェクトを生成し、_e.shiftKey
_などを探してみましたが、運がありませんでした。
私はChrome 17を使用しています
私の解決策:
var keys = {};
window.onkeyup = function(e) { keys[e.keyCode] = false; }
window.onkeydown = function(e) { keys[e.keyCode] = true; }
スクリプト内のどこかでキーが押されているかどうかを確認できます
keys["code of the key"]
正しい場合、キーが押されます。
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];
}
それはあなたが望むものを達成する必要があります。
/*
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 */}
他の人々は以前にこの種の質問をしたことがあります(ただし、ここには明らかなだましは見当たりませんが)。
答えは、keydown
イベント(およびそのツインkeyup
)がすべての情報であると思います。繰り返しはオペレーティングシステムにしっかりと接続されており、アプリケーションプログラムは、キーの実際の状態をBIOSに照会する機会をあまり得られません。
あなたができること、そしておそらくあなたがこれを機能させるために必要なのは、プログラムでキーのバウンスを解除することです。基本的に、keydown
とkeyup
を自分で評価できますが、最後のkeyup
...の後にあまりにも早く発生する場合はkeydown
eventを無視できます。 keyup
への応答を遅らせて、0.25秒のkeydown
のような後続のkeyup
イベントがないことを確認します。
これには、タイマーアクティビティの使用、および以前のイベントのミリ秒時間の記録が含まれます。非常に魅力的なソリューションとは言えませんが、...
ブラウザーに既にビルトインされているものがあるかどうかを確認するためにここに行きましたが、そうではないようです。これは私のソリューションです(ロバートの答えに非常に似ています):
_"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')
を使用してキーが押されたかどうかを確認できます。
次のコードは私が使用しているものです:
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の両方が使用されます。
上記の回答をスキャンしたところ、提案されたkeydown
/keyup
アプローチは特別な状況下でのみ機能します。ユーザーがAltキーを押しながらタブを離れるか、キージェスチャを使用して新しいブラウザーウィンドウまたはタブを開くと、keydown
が登録されます。これは、その時点ではキーがどうかを判断できないためです。 Webアプリが監視しているもの、または標準のブラウザーまたはOSショートカットです。ブラウザのページに戻ると、キーは保持されていると思われますが、その間にリリースされました。または、ユーザーがマウスで別のタブまたはアプリケーションに切り替えてから、ページの外にリリースされている間、いくつかのキーが単に保持されます。
修飾キー(Shift
など)は、mousemove
などを介して監視できます。タブで戻るときに、少なくとも1つのマウス操作が想定されます。これはよくあることです。
他のほとんどのキー(修飾子、Tab
、Delete
を除く、ただしSpace
、Enter
を含む)の場合、keypress
の監視はほとんどのアプリケーション-キーが押されたままになります。ただし、keypress
発火の周期性のため、キーのリセットには多少の遅延があります。基本的に、keypress
が発火し続けない場合、ほとんどのキーを除外することができます。これは、修飾子と組み合わせてかなり気密性がありますが、Tab
とBackspace
をどう処理するかについては検討していません。
このDOMの弱点を抽象化するライブラリがあるか、またはDOMの標準的な変更がそれを処理してくれると思います。これはかなり古い質問です。
これは非常に古い質問ですが、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!)
これがお役に立てば幸いです。