0

ユーザーが特定の期間内に特定の文字セットを入力したかどうかを判断しようとしています。

動作するものを作成したと思いますが、グローバル変数 toMatch を使用しているため、あまり良くないことはわかっています。varキーワードなしで setInterval で宣言しました。スコープの考え方は私にとって混乱を招きますが、私は学ぼうとしています.誰かがこれを行うためのより良い方法を提供できるのではないでしょうか?

//set the toMatch array equal to the character codes for the word 'test'
//reset it to its original value every 2seconds
var matchTime = setInterval(function(){ console.log('toMatch reset'); toMatch = [84,69, 83, 84];}, 2000);


document.addEventListener("keydown", function(e){

   var key = e.which;
   findMatches(key);

});

function findMatches(key){

    //if the key is in the first position in the array, remove it
    if (key == toMatch[0]){
      toMatch.shift();

    }
      console.log(toMatch);

  //if all shifted out, clear the interval
  if (toMatch.length == 0 ) {
    window.clearInterval(matchTime);
    alert('typed \'test\' within two seconds');
  }

}

jsbin

ありがとうございました

4

2 に答える 2

0

これを試して

function listenForWord(word) {
    word = word.toUpperCase(); // event char codes are in upper case
    var counter = 0,
        time = 0;
    // I used jQuery, you could also use addEventListener but don't
    // forget to use attachEvent so it works in all browsers!
    $(document).keydown(function (e) {
        // Because the code is inside a function, the variable
        // word is available at this level but is not global
        var currentTime = new Date().getTime();
        if (currentTime - time > 1000) {
            // If the user waits more than 1 second to type the next letter
            // The counter is reset, I'm not sure if this is what you want!
            counter = 0;
        }
        var character = word.charCodeAt(counter),
            first = word.charCodeAt(0);
        if (character == e.which) {
            counter++;
        } else if (character == first) {
            counter = 1;
        } else {
            counter = 0;
        }
        if (counter == word.length) {
            counter = 0;
            alert("You typed " + word + " fast enough");
        }
        time = currentTime;
    });
}

listenForWord("test");
// You could potentially call this function with other words
// And it will work

setInterval私のコードには呼び出しがないことに注意してください.

これは、ユーザーが 4 文字の単語を入力するのに最大 4 秒 (各キーの入力間隔が 1 秒以内) であるため、あなたのものとまったく同じではありません。

設定された 2 秒の制限時間内に 4 文字すべてを入力したことをテストする場合は、最初のキーが押されたときに時間を保存するようにロジックを再定式化できます。次に、時間ではなく現在の時間をその時間と比較します。最後のキー押しから。

于 2013-02-19T23:17:52.217 に答える
0

主な質問がグローバル変数を回避する方法である場合、簡単な答えは、すぐに呼び出される関数式 (IIFE) を調べることです。Ben Alman の良い記事があります: http://benalman.com/news/2010/11/immediately-invoked-function-expression/

基本的に、すべての変数/関数を独自のスコープにカプセル化し、すぐに呼び出します。最小限の変更でコードに適用できます。

//IIFE 開始
(関数(){
    // IIFE スコープ内で toMatch 変数を宣言 - グローバル スコープを汚染するのを防ぎます
    var toMatch;
    // toMatch 配列を「test」という単語の文字コードに等しく設定します
    // 2 秒ごとに元の値にリセットします
    var matchTime = setInterval(関数(){
        console.log('toMatch リセット');
        toMatch = [84,69, 83, 84];
    }、2000);

    document.addEventListener("keydown", function(e){
         var key = e.which;
         findMatches(キー);
    });

    関数findMatches(キー){

        //キーが配列の最初の位置にある場合は、それを削除します
        if (key == toMatch[0]){
            toMatch.shift();
        }
        console.log(toMatch);

        //すべてシフトアウトした場合、間隔をクリアします
        if (toMatch.length == 0) {
            window.clearInterval(matchTime);
            alert('\'test\' を 2 秒以内に入力しました');
        }

    };
})();


console.log(window.toMatch) // toMatch はグローバル変数ではなくなりました

于 2013-02-19T23:25:47.783 に答える