2015-04-27 1 views
0

IE не всегда отвечает на событие keyup в одном из моих сценариев.Отключить ключ, выпущенный без использования события keyup - Javascript

Я искал альтернативный способ определить, был ли выпущен ключ.

Учитывая, что удерживаемая клавиша повторяет событие 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>

+1

Это, возможно, звучит как [проблема XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Если ваше окно теряет фокус, оно больше не будет принимать ключевые события *. EG нажмите клавишу вниз, вы получите keydown, теперь щелкните в другое приложение и отпустите ключ - вы не видите keyup, так как это событие произошло в другом приложении. Вернитесь немного назад и, возможно, переосмыслите, для чего вы хотите получить это событие? –

ответ

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>