检测不使用keyup事件释放的密钥 - Javascript

时间:2015-04-27 12:34:50

标签: javascript keyup

IE似乎并不总是响应我的一个脚本中的键盘事件。

我找了另一种检测密钥是否已被释放的方法。

假设一个按下的键每隔一段时间重复一次keydown事件(Mac上的修饰键除外),我认为可以增加一个变量并监听它停止递增的点。当它停止递增时,该键已被释放?

不幸的是,偶尔(并非总是如此),我的脚本正在检测到递增的结束,而键仍然按下。如果按键重复短暂间隔,则往往会失败更多。我已经使用IE和FF进行了测试。

我在检查每个增量之间允许2秒钟。将我的Windows控制面板设置为最慢的键盘设置,1秒就足够了。

<!DOCTYPE html>
<html>

<head>

  <title>Detect keyup not using keyup event using Javascript</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <script type="text/javascript">
    // opening variables
    var keyDownCount = 0;
    var nextLastTimeout1 = false;
    var nextLastTimeout2 = false;
    var lastCount = false;
    var nextCount = false;

     // function to compare the last two outcomes for keyDownCount by    assigning them to variables lastCount and nextCount
    function nextLastCount() {
      if (lastCount) {
        nextCount = keyDownCount;
        if (lastCount === nextCount) {
          // clear any outstanding timeouts
          clearTimeout(nextLastTimeout1);
          clearTimeout(nextLastTimeout2);
          // they match, display the count in the html
          document.getElementById('matched-next-last').innerHTML = keyDownCount;
        } else {
          // clear any outstanding timeouts
          clearTimeout(nextLastTimeout1);
          clearTimeout(nextLastTimeout2);
          // reset variable
          lastCount = false;
          // they don't match, call the function again after allowing sufficient time for the key repetition rate to increment the keyDownCount 
          nextLastTimeout1 = self.setTimeout("nextLastCount()", 2000);
        }
      } else {
        lastCount = keyDownCount;
        if (lastCount === nextCount) {
          // clear any outstanding timeouts
          clearTimeout(nextLastTimeout1);
          clearTimeout(nextLastTimeout2);
          // they match, display the count in the html
          document.getElementById('matched-next-last').innerHTML = keyDownCount;
        } else {
          // clear any outstanding timeouts
          clearTimeout(nextLastTimeout1);
          clearTimeout(nextLastTimeout2);
          // reset variable
          nextCount = false;
          // they don't match, call the function again after allowing sufficient time for the key repetition rate to increment the keyDownCount
          nextLastTimeout2 = self.setTimeout("nextLastCount", 2000);
        }
      }
    }

     // keydown listener
    document.addEventListener('keydown', function(e) {
      if (!e) e = window.event;
      // listen for alt key down
      if (e.altKey) {
        if (keyDownCount === 0) {
          // call nextLastCount() to start comparing the last two outcomes for keyDownCount
          // allow sufficient time for the key repetition rate to increment keyDownCount 
          setTimeout("nextLastCount()", 2000);
        }
        // increment the counter on each keydown repeat
        keyDownCount++;
        // display the current count in the html
        document.getElementById('display-count').innerHTML = keyDownCount;
      }
    });

     // keyup listener
    document.addEventListener('keyup', function(e) {
      if (!e) e = window.event;
      // listen for alt key released
      if (!e.altKey) {
        // clear any outstanding timeouts
        clearTimeout(nextLastTimeout1);
        clearTimeout(nextLastTimeout2);
        // reset the counter and the html fields when the keys are released
        keyDownCount = 0;
        document.getElementById('display-count').innerHTML = keyDownCount;
        document.getElementById('matched-next-last').innerHTML = "";
      }
    });
  </script>

</head>

<body>
  <p>Hold down the alt key to start the counter, relese to reset.</p>
  <p>keyDownCount is: <span id="display-count"></span>
  </p>
  <p>Matching next and last detected on key count of: <span style="color:blue;" id="matched-next-last"></span>
  </p>
</body>

</html>

2 个答案:

答案 0 :(得分:1)

万一其他人可能需要这个,我解决了如下问题。简化代码,只有一次超时。

在Firefox中,当alt键关闭时按空格键将用于模拟非键盘事件。

<!DOCTYPE html>
<html>
<head>

<title>Detect keyup without using keyup event</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript">

// opening variables
var keyDownCount = 0;
var nextLastTimeout = false;
var nextCount = false;
var lastCount = false;
var nextCountTime = false;
var lastCountTime = false;

// function to compare the last two outcomes for keyDownCount by assigning them to variables lastCount and nextCount
function nextLastCount() {
    if (lastCount) {
    nextCount = keyDownCount;
    // record the time for use in calculating the keyboard delay
    nextCountTime = +new Date(); // milliseconds since 01 January, 1970
        if (lastCount === nextCount) {
        // they match, display the count in the html
        document.getElementById('matched-next-last').innerHTML = keyDownCount;
        }else{
        // reset variable
        lastCount = false;
        }
    }else{
        lastCount = keyDownCount;
        // record the time for use in calculating the keyboard delay
        lastCountTime = +new Date(); // milliseconds since 01 January, 1970
        if (lastCount === nextCount) { 
        // they match, display the count in the html
        document.getElementById('matched-next-last').innerHTML = keyDownCount;
        }else{
        // reset variable
        nextCount = false;
        }
    }
}

// keydown listener
document.addEventListener('keydown',function(e) {
if(!e) e = window.event; 
    // listen for alt key down
    if (e.altKey) {
    // increment the counter on each keydown repeat
    keyDownCount++;
    // display the current count in the html
    document.getElementById('display-count').innerHTML = keyDownCount;
    // see below
    clearTimeout(nextLastTimeout);
    // call function
    nextLastCount();
        // calculate the keyboard delay i.e. time between repeated keystrokes
        if (nextCountTime && lastCountTime)  {
        // returns an always positive value in milliseconds 
        var keyboardDelay = Math.abs(nextCountTime - lastCountTime);
        }else{
        // in the first few increments both count times are not available, use an estimate
        var keyboardDelay = 3000; // also 500ms added below
        }
    // call nextLastCount() again, but on a delay that exceeds the keyboard delay
    // .. for safety, add 500ms to the calculated / estimated keyboard delay
    // this timeout will only complete when the increments stop
    // .. see clearTimeout(nextLastStickyTimeout) above
    nextLastTimeout = setTimeout("nextLastCount()",keyboardDelay + 500);
    }
 });

// keyup listener
document.addEventListener('keyup',function(e) {
if(!e) e = window.event; 
    // listen for alt key released
    if (!e.altKey) {
    // clear any outstanding timeouts
    clearTimeout(nextLastTimeout);
    // reset the counter and the html fields when the keys are released
    keyDownCount = 0;
    document.getElementById('display-count').innerHTML = keyDownCount;
    document.getElementById('matched-next-last').innerHTML = "";
    }
});

</script>

</head>

<body>
<p>Hold down the alt key to start the counter, release to reset.</p>
<p>In Firefox, pressing the spacebar whilst the alt key is down will simulate a non keyup event</p>
<p>keyDownCount is: <span id="display-count"></span></p>
<p>Matching next and last detected on key count of: <span style="color:blue;"id="matched-next-last"></span></p>
</body>

</html>

答案 1 :(得分:0)

这似乎应该已经解决了。这是关于最佳输入库的SO问题:which is the best Javascript Keyboard event library.(Hotkeys,Shortcuts )

理想情况下,你不想重新发明轮子。