5

Javascript / jQueryを使用して、誰かがキーを押したときに、キーダウンイベントまたは同等のイベントを自動的に繰り返すにはどうすればよいですか?

私が実際に望んでいるのは、キーが押されているかどうかを確認できることですが、ここでの他の質問からは、それは不可能のようです。推奨される回避策は、キーダウンイベントとキーアップイベントを記録し、キーダウンイベントが記録され、その後のキーアップがない場合はキーがダウンしていると想定することです。

私の場合、その解決策は問題にぶつかります。私はオンライン実験を設計しています。ユーザーは、実験全体で「T」キーを押したままにし、決して離さないようにする必要があります。実験は複数の試行で構成されており、各試行は前の試行で記録された情報にアクセスできません。したがって、トライアル1はTのキーダウンを記録できますが、トライアル2はそのレコードにアクセスできないため、Tがダウンしたかどうかはわかりません。

ここで、Tキーを押したままにすると、Tに対して自動的に繰り返されるキーダウンイベントが生成される場合、トライアル2はTの次のキーダウンイベントをキャッチするだけなので、問題はありません。しかし、少なくともFirefoxでは、キーを押したままにすると自動的にキーダウンイベントが繰り返されることはないようです。私が見ることができることから、異なるブラウザがキーを押したままにする方法に変化があるように思われます。私の問題を解決するための良いクロスブラウザの方法は何ですか?

ちなみに、それが重要な場合は、これがすべて行われている間に、他のキーのキーアップイベントとキーダウンイベントも検出できる必要があります。

編集:コメントのいくつかを読んだ後、私は戻って、通常の状況下で実際にキーダウンイベントが繰り返されることを確認しました。しかし、私は実際にそれらを必要とする特定の状況でそれらを取得しません。問題を切り分けると思う簡単なコードがいくつかあります。

<!DOCTYPE html>
<html>

<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
</head>

<body>
<div id="target"></div>
</body>

<script type="text/javascript">

var i;
function foo() {
    i++;
    $('#target').html(i);
}

function doTrial() { // do trial
    i=0;
    $(document).keydown(foo);
    $(document).keyup(endTrial);
}

function endTrial() { // end trial
    $('#target').html('');
    $(document).unbind('keydown',foo);
    $(document).unbind('keyup',endTrial);
    doTrial();
}

doTrial();

</script>

</html>

キーを押したまま離してからもう一度押すと、期待どおりの動作になります。つまり、キーを押している間は増加し、離すと消え、押すと再び増加し始めるカウンターがあります。また。

しかし、2つのキーを押してから1つを離すと、もう1つの(リリースされていない)キーがキーダウンイベントを送信し続け、カウンターが(リセット後)増加し続けると思います。実際、それは起こりません。なぜ、どのようにそれを実現するのか、何か考えはありますか?

4

2 に答える 2

7

これを試したブラウザでは、入力可能なキーを押したままにすると、キーダウンイベントが繰り返し発生しました。これがあなたが実際に解決する必要のある問題であるかどうかはわかりません。

しかし、それを解決する必要があると思った場合、または繰り返し率を自分で制御したい場合は、次のように行うことができます。

  1. キーダウンとキーアップのイベントをキャプチャします。
  2. キーダウン時に、キーがまだダウンしていることを知りたい場合に頻繁に起動するインターバルタイマーを設定します。
  3. そのキーのキーアップ時に、インターバルタイマーを停止します。
  4. キーが押されている限り、クロスブラウザ方式で繰り返し通知が届きます。

ここでの作業デモ:http://jsfiddle.net/jfriend00/XbZYs/

var downTimer;
var lastKey;
$(document.body).keydown(function(e) {
    // if not still the same key, stop the timer
    if (e.which !== lastKey) {
        if (downTimer) {
            clearInterval(downTimer);
            downTimer = null;
        }
    }
    // remember previous key
    lastKey = e.which;
    if (!downTimer) {
        // start timer
        downTimer = setInterval(function() {
            $("#result").append("+");
        }, 125);
    }
}).keyup(function(e) {
    // stop timer
    if (downTimer) {
        clearInterval(downTimer);
        downTimer = null;
        lastKey = 0;
    }
});

キーが上がるまで永久に自動リピートしたい場合、その間に他のキーが押されて放されても、それらの他のキーに独自の自動リピートを実行させたい場合、OSはその動作をipmlementしないので、自分で実装する必要があります。キーリピートイベントごとにコールバック関数を呼び出す次のようなことを行うことができます。

作業デモ: http: //jsfiddle.net/jfriend00/aD3Eg/

// this is called for every manufactured repeat event
// the frequency of the repeat event is determined by the time value set
// on setInterval() below
function repeatCallback(key) {
    $("#result").append(key + " ");
}

var repeatState = {};
$(document.body).keydown(function(e) {
    var key = e.which;
    // if no time yet for this key, then start one
    if (!repeatState[key]) {
        // make copy of key code because `e` gets reused
        // by other events in IE so it won't be preserved
        repeatState[key] = setInterval(function() {
            repeatCallback(key);
        }, 125);
    } else {
        // nothing really to do here
        // The key was pressed, but there is already a timer
        // firing for it
    }
}).keyup(function(e) {
    // if we have a timer for this key, then stop it 
    // and delete it from the repeatState object
    var key = e.which;
    var timer = repeatState[key];
    if (timer) {
        clearInterval(timer);
        delete repeatState[key];
    }
});
​

repeatCallback関数は、これらの製造されたすべての自動リピートイベントに対して呼び出され、自動リピートするキーを渡します。</ p>

于 2012-12-25T05:11:50.160 に答える
0

このjQueryプラグインを見てください:fastKeys私は、それがあなたが望む/必要なものだと思います...

于 2012-12-26T19:08:11.640 に答える