2

これは少し奇妙なものなので、明らかな何かが欠けているか、これはこれらのイベントがブラウザで実装される方法の欠陥であると思います。

最初に、この問題が発生するシナリオの例を要約してから、個別のケース例を示します。

矢印キーはプレーヤーを移動するために使用されます(ページ上の任意の場所でキーが押されるたびにhandleKeyDown関数が起動されるため)。同様に、キーが解放されるたびに、別の関数が起動されます(handleKeyUp)。

あなた(プレイヤー)が左キーを押し続けると、handleKeyDown関数が繰り返しトリガーされます(確かに、これはあなたが期待するものと名前が意味するものに反すると思いますが、それにもかかわらず、これはすべてのブラウザーで正常な動作です。ほら)。

つまり、次のようになります。プレーヤーは、その方向に歩く方向を保持します。次に、方向を押したまま歩き続けるときに、数字キー(ホットキーアイテムの場合)を押します。ここで何が起こるかというと、ホットキーのあるアイテムの数字キーを離すと、プレイヤーの動きの繰り返しが止まるだけです!

私はこの振る舞いの非常に小さな孤立した例を書きました:

<html>
<head>
    <script type='text/javascript' src='jquery-1.5.1.min.js'></script>
    <script type='text/javascript'>
        var log = {};
        var keyState = {};
        var keyCount = {'down': 0, 'up': 0};
        window.addEventListener('keydown', handleKeyDown, false);
        window.addEventListener('keyup', handleKeyUp, false);
        function handleKeyDown (e)
            {
            keyState[e.keyCode] = true;
            keyCount.down++;
            log.prepend(" ["+e.keyCode+"] ");
            return false;
            }
        function handleKeyUp (e)
            {
            keyState[e.keyCode] = false;
            keyCount.down++;
            return true;
            }
        $(function(){log = $('#log');});
    </script>
</head>
<body>
    <div id='debug'></div>
    <div id='log'></div>
</body>

ここで試すこともできます:

http://sikosoft.net/keys.html

ページ上の任意のキーを押すと、keyCodeがページに表示されます。キーを押し続けると、キーコードが何度も繰り返されます。

最初のキーを押したまま別のキーを押すと、動作がおかしくなります。その最近のキーを離すと、最初のキーから繰り返しが停止します。興味深いことに、例を試して1つのキーを押した後、2番目のキーを押したまま、2番目のキーを離す代わりに、最初のキーを放すと、2番目のキーが繰り返されます。

つまり、キーアップイベントが発生すると、以前のキーで発生したキーダウンイベントの繰り返しが終了するように見えます。

両方のイベント処理関数でfalseを返す、trueを返す、keydownの代わりにkeypressを試す、key-stateを保存する、ボタンのkeystateがまだtrueの場合は移動を続けるなど、さまざまなことを試しましたが、すべてがうまくいきません。つまり、キーアップが実行されると、アクティブに伝播しているキーダウンイベントがすべて強制終了されます。JavaScript Madness:Keyboard Eventsを読みましたが、この特定の種類の動作については何も表示されていません。

これはキーイベントの実装に関する設計上の欠陥ですか、それとも何かが足りないのですか?Chrome、IE、Firefoxでも同じ動作が見られます。

アドバイスや意見はありますか?

4

3 に答える 3

7

これがOS/環境の動作方法であり、その結果、ブラウザの動作方法です。

キーダウンの繰り返しは、ブラウザ内の別のキーからのキーアップ後に起動し続けるべきではありません。他の場所ではそのように動作しないためです。メモ帳、vim、pico、または使用するテキストエディタを開き、同じ一連のイベントを実行します。キーアップ後、最初に押したキーが新しい文字を印刷し続けないことがわかります。これがOSで設計された方法であり、その結果、エディターやブラウザーなどに伝達される方法です。

于 2011-04-30T13:01:15.557 に答える
0

これが私のキーボード入力用のシステムです。ここで、繰り返しキーを抽出して自分で使用する方法を確認できます。別の答えが誤って想定されているため、保持されているキーに気付くことができ、オペレーティングシステムに依存することはありません。


var down = [140]; //make an array to cover all the keypresses you should need with a normal keyboard

document.addEventListener('keydown', function(event) {
  if (down[event.keyCode]){
    return;
  } else {
   //do the normal things you do when you get key presses
  down[event.keyCode]=true;
  }
}, true);
document.addEventListener('keyup', function(event) {
  down[event.keyCode]=false;
   //do the normal things you do when you get key releases
}, true);

配列の「下」と、必要なキーコードの配列内の位置を確認するだけです。ゲーム入力のキーリピートを防ぐために使用します。お役に立てれば!

于 2019-01-17T17:46:54.513 に答える
0

将来の読者のために、これを試すことができます。

let keys = {};

document.onkeydown = e => {
  if (!keys[e.code]) {
    keys[e.code] = true;
  }
};

document.onkeyup = e => (keys[e.code] = false);

move = () => {
  if (keys["ArrowLeft"]) {
    console.log("ArrowLeft")
  }
  if (keys["ArrowRight"]) {
    console.log("ArrowRight")
  }
  if (keys["ArrowDown"]) {
    console.log("ArrowDown")
  }
  if (keys["ArrowUp"]) {
    console.log("ArrowUp")
  }
};

setInterval(move, 100);

于 2021-10-05T14:39:48.620 に答える