触发密钥时,Javascript会忘记其他keydown

时间:2014-06-08 10:43:40

标签: javascript jquery keyboard keypress

我跟着this question/answer创建了一个多按键检测器。它按预期工作:你按 D 并且方块向右移动,然后按 S ,同时按 D 并且方块以角度移动。到现在为止还挺好。但是,如果您同时按 D S 并且取消 S ,则方块将停止移动。预期的行为是它继续向右移动,因为你仍在按 D

此处 a jsfiddle demo I'm making (我的网站)。

那么,为什么.keyup()使其他.keydown()事件无效?这是违规的jQuery代码:

// Check if it's a function
function isFunction(functionToCheck) {
    var getType = {};
    return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}

// Store the keys pressed and callback for each key
var keys = {};
var keycalls = {};

// Loop and call all the needed callbacks
function run_keys() {
    $.each(keys, function (index, value) {
        if (value == true) {
            console.log(keys);
            var fun = keycalls[index];
            if (isFunction(fun))
                fun();
        }
    });
}
// Store a key
$(document).keydown(function (e) {
    keys[e.which] = true;
    run_keys();
});
// Delete a key
$(document).keyup(function (e) {
    delete keys[e.which];
    run_keys();
});
// Assign a callback to a key
keyboard = function (key, callback) {
    console.log(callback);
    keycalls[key.toUpperCase().charCodeAt()] = callback;
}
// Assign keys
// Assign w to up action
keyboard("w", function () {
    $(".keyboard").animate({
        'top': "-=5px"
    }, 0);
});
keyboard("a", function () {
    $(".keyboard").animate({
        'left': "-=5px"
    }, 0);
});
keyboard("s", function () {
    $(".keyboard").animate({
        'top': "+=5px"
    }, 0);
});
keyboard("d", function () {
    $(".keyboard").animate({
        'left': "+=5px"
    }, 0);
});

免责声明:这只是为了娱乐和学习,而不是有游戏引擎。我知道有很多好的可用。

更新

我认为其中一个解决方案是为调用run_keys()创建一个独立的循环,但我想尽可能避免这种情况。 It works,但我仍然对这个问题感兴趣。

1 个答案:

答案 0 :(得分:1)

我相信你的问题来自 keyup 之后 keypress 事件的结束,而不是任何事情"出错",使用 setTimout 循环,而不是在每个处理程序的末尾调用run_keys


以下是 setTimeout循环

的示例
(function looper() {
    run_keys();
    window.setTimeout(looper, 100);
}());

它有点像 setInterval 但延迟在调用之后启动,这意味着您不会获得(相同类型)级联错误可以使用 setInterval