Как предотвратить прерывание события keyup события keydown в jQuery?

Возможный дубликат:
Кросс-браузерный способ автоматически повторять события нажатия клавиши, когда клавиша удерживается нажатой

Я пытаюсь создать простую игру на JavaScript/CSS/HTML и использую jQuery (и немного Underscore) для обработки нажатий клавиш. Игрок управляет блоком с помощью клавиш со стрелками. У меня возникла проблема с обработкой нескольких нажатий клавиш одновременно. У меня есть система, в которой закрытие отслеживает все нажатые клавиши со стрелками. Это хорошо работает, если игрок нажимает клавиши в следующей последовательности:

  1. Игрок нажимает Вниз (блок движется вниз)
  2. Игрок нажимает влево (блок движется по диагонали вниз-влево)
  3. Игрок отпускает вниз (блок движется влево)
  4. Игрок отпускает левый (блок останавливается

Однако блок останавливается, если шаги 3 и 4 меняются местами. Вот что на самом деле происходит в этом случае:

  1. Игрок нажимает Вниз (блок движется вниз)
  2. Игрок нажимает влево (блок движется по диагонали вниз-влево)
  3. Игрок отпускает левый (блок останавливается)

Ожидаемое поведение состоит в том, что на шаге 3 блок будет продолжать двигаться вниз, а не полностью останавливаться.

Судя по следам, которые я вставил в код, кажется, что событие нажатия клавиши фактически останавливает распространение дальнейших событий нажатия клавиши, даже когда мой палец все еще держит одну из клавиш со стрелками.

Вот фрагмент соответствующего кода. Может ли кто-нибудь сказать мне, где может быть проблема?

// Creates an animation handler for a specific element.
// Animation reacts to any changes as they are submitted
var getMovementAnimator = function(element) {
    var params = {},
        $element = $(element);
    return function(changes) {
        _.each(changes, function(val, key) {
            // Remove null or zeroish keys from animation params
            if ( (val == 0 || !val) && _.has(params, key)) {
                delete params[key];
            } else {
                params[key] = '+=' + val + 'px';
            }
        });
        $element.animate(params, {duration: 0, queue: false});
        console.log(params);
    };
};

// Determines direction and speed of movement for an element
// after a keypress event
var getMovementChange = function(keyEvent, keydown) {
    var isMoving = !!keydown,
        params   = {},
        dir      = '',
        speed    = keydown ? 5 : 0,
        arrows   = {left: 37, up: 38, right: 39, down: 40};
    switch (keyEvent.which) {
        case arrows.left:
            dir = 'left';
            speed = -speed;
            break;
        case arrows.up:
            dir = 'top';
            speed = -speed;
            break;
        case arrows.right:
            dir = 'left';
            break;
        case arrows.down:
            dir = 'top';
            break;
    }
    // If key hit not one of above, do nothing
    if (!dir) {
        return false;
    }
    if (!speed) {
        console.log('key up: ', dir);
    }
    params[dir] = speed;
    return params;
}

// Sets up key handlers
$(document).ready(function() {
    var board = $('#board'),
        animatePlayer = getMovementAnimator('.player');
    $(document).keydown(function(e) {
        e.preventDefault();
        var changes = getMovementChange(e, true);
        animatePlayer(changes);
    }).keyup(function(e) {
        e.preventDefault();
        var changes = getMovementChange(e, false);
        animatePlayer(changes);
    });
});

person fruchtose    schedule 03.01.2013    source источник


Ответы (1)


Дальнейший поиск в Stack Overflow (используя правильные ключевые слова) показал мне, что проблема, которую я вижу, на самом деле не является ошибкой в ​​моем коде. Скорее, это ожидаемое поведение операционной системы.

Однако я нашел обходной путь, который, как мне кажется, решит проблему.

person fruchtose    schedule 03.01.2013