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(function(){
        console.log('toMatch reset');
        toMatch = [84,69, 83, 84];
    }, 2000);

    document.addEventListener("keydown", function(e){
         var key = e.which;
         查找匹配(键);
    });

    功能查找匹配(键){

        //如果键在数组的第一个位置,则将其删除
        if (key == toMatch[0]){
            toMatch.shift();
        }
        控制台.log(toMatch);

        //如果全部移出,清除间隔
        如果(toMatch.length == 0){
            window.clearInterval(matchTime);
            alert('在两秒内输入了\'test\'');
        }

    };
})();


console.log(window.toMatch) // 现在 toMatch 不是全局变量

于 2013-02-19T23:25:47.783 回答