Это немного странно, поэтому я полагаю, что я либо пропустил что-то очевидное, либо это ошибка, связанная с тем, как эти события реализованы в браузерах.keydown (повторение) ломается, когда срабатывает событие keyup (для ключа ANOTHER)
Позвольте мне вначале обобщить пример сценария, который возникает в этой проблеме, прежде чем предоставить изолированный пример case;
Клавиши со стрелками используются для перемещения плеера (поскольку функция handleKeyDown запускается в любое время, когда ключ попадает в любую точку страницы). Аналогично, в любое время, когда выдается ключ, запускается другая функция (handleKeyUp).
Поскольку вы (игрок) удерживаете левую клавишу вниз, функция handleKeyDown повторно запускается (что, по общему признанию, я считаю, что вы не согласны с тем, что вы ожидаете и что подразумевает это имя, но, тем не менее, это нормальное поведение во всех браузерах как Я уверен, вы знаете).
Так вот что происходит: игрок держит направление, чтобы идти в этом направлении; затем нажмите цифровую клавишу (для элемента с горячим нажатием). Они продолжают ходить, удерживая направление вниз. Что происходит здесь, так это то, что когда вы отпускаете номер ключа для элемента с горячим нажатием, повторение движения игрока просто прекращается!
Я написал очень маленький изолированный пример такого поведения:
<html>
<head>
<script type='text/javascript' src='jquery-1.5.1.min.js'></script>
<script type='text/javascript'>
var log = {};
var keyState = {};
var keyCount = {'down': 0, 'up': 0};
window.addEventListener('keydown', handleKeyDown, false);
window.addEventListener('keyup', handleKeyUp, false);
function handleKeyDown (e)
{
keyState[e.keyCode] = true;
keyCount.down++;
log.prepend(" ["+e.keyCode+"] ");
return false;
}
function handleKeyUp (e)
{
keyState[e.keyCode] = false;
keyCount.down++;
return true;
}
$(function(){log = $('#log');});
</script>
</head>
<body>
<div id='debug'></div>
<div id='log'></div>
</body>
Вы также можете попробовать его здесь:
Нажмите клавиши на странице и вы увидите, что keyCode появляется на странице. Когда вы удерживаете клавишу, код ключа повторяется снова и снова.
Поведение становится причудливым при нажатии на другой ключ, в то время как начальный ключ все еще удерживается. После выпуска этого последнего ключа повторение останавливается от первого ключа. Интересно, что если вы попробуете пример и удерживаете один ключ, а затем удерживаете второй ключ, но вместо того, чтобы отпустить второй, отпустите первый: второй ключ продолжает повторяться.
Так что, похоже, что при запуске события keyup оно прекращает повторение событий keydown, которые были запущены на более раннем ключе.
Я пробовал всевозможные вещи, начиная с использования возвращаемого значения false в обеих функциях обработки событий, возвращая true, пробуя keypress вместо keydown, сохраняя ключевые состояния и продолжая движение, если keystate кнопки по-прежнему верна, но что все сводится к тому, что при запуске keyup активно активно распространяются события, связанные с keydown. Я прочитал JavaScript Madness: Keyboard Events, и я ничего не вижу об этом конкретном поведении.
Является ли это недостатком дизайна с реализацией ключевых событий, или я что-то упускаю? Я наблюдаю такое же поведение в Chrome, IE & Firefox.
Любой совет?
Я чувствую себя настолько глупо, что даже не проверяю это за пределами контекста браузера - вы абсолютно правы; такое же поведение происходит у меня в Notepad ++. Похоже, я все-таки должен пойти по-другому. Спасибо за разъяснение о поведении. :) – Lev
Вам, скорее всего, придется настроить какое-то решение на основе таймера. См. Http://bonsaiden.github.com/JavaScript-Garden/#other для начала работы. –