检测某些字符是否在一定时间内输入

时间:2013-02-19 22:41:41

标签: javascript

我正在尝试确定用户是否在特定持续时间内键入了一组特定字符。

我猜想,我做了一些有用的东西,但我知道它不是很好,因为它使用全局变量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

谢谢

2 个答案:

答案 0 :(得分: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个字符,你可以重新设定逻辑,而不是在按下第一个键时存储时间 - 然后将当前时间与当时时间进行比较比起上次按键的时间。

答案 1 :(得分:0)

如果您的主要问题是如何避免全局变量,那么一个简单的答案就是查看立即调用的函数表达式(IIFE)。本·阿尔曼在这里有一篇好文章:http://benalman.com/news/2010/11/immediately-invoked-function-expression/

它基本上将所有变量/函数封装到自己的作用域中,并立即调用它自己。您只需稍加更改即可将其应用于您的代码。


//Begin IIFE
(function(){
    //declare toMatch variable inside IIFE scope - prevents it from polluting the global scope
    var toMatch;
    //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');
        }

    };
})();


console.log(window.toMatch) // now toMatch isn't a global variable