11

我和这个人有同样的问题How to disable duplicate keydown in jQuery,只是我没有使用 jQuery 所以我很难将它翻译成“纯” JavaScript,无论如何我已经设置switch了一些键的大小写和当我按住右箭头键时,我的 div 正在飞行。另外,如果这不是问题,你能告诉我当我放开右箭头键时停止 div 移动的最简单方法是什么,我是否必须用clearIntervalor 制作一个新的开关盒?

switch (keyPressed) {
    case 39:
        setInterval(movFwr, 50);
        break;
}

function movFwr() {
    if (currPos == 1000) {
        a.style.left = 1000 + "px";
    } else currPos += 10;
    a.style.left = trenutnaPozicija + "px";
}

对不起,伙计们,我有点忙,我正在测试所有可能性,到目前为止我已经看到了一些有趣的建议。这些天我都会测试他们,然后评估你在这个网站上所做的事情。我必须说伟大的社区。谢谢大家的帮助 :)

4

4 回答 4

20

像这样的东西应该可以解决问题;

var down = false;
document.addEventListener('keydown', function () {
    if(down) return;
    down = true;

    // your magic code here
}, false);

document.addEventListener('keyup', function () {
    down = false;
}, false);
于 2013-07-07T18:10:11.273 回答
2

我会记录时间并阻止采取行动,除非经过足够的时间,例如使用Date.now

var lastPress = 0;

function myListener() {
    var now = Date.now();
    if (now - lastPress < 1000) return; // less than a second ago, stop
    lastPress = now;
    // continue..
}

这可以做成一个更通用的函数

function restrict(func, minDuration) {
    var lastPress = 0;
    return function () {
        var now = Date.now();
        if (now - lastPress < minDuration) return; // or `throw`
        lastPress = now;
        return func.apply(this, arguments);
    };
}
// now, for example
foo = function () {console.log('foo');};
bar = restrict(foo, 200); // only permit up to once every 200ms
bar(); // logs "foo"
bar(); // void as less than 200ms passed
于 2013-07-07T18:12:25.163 回答
1

keydown要忽略由按键重复引起的按键事件,请跟踪在和keyup事件期间按下了哪些按键。

var pressedKeys = [];
function keydownHandler(e) {
    var isRepeating = !!pressedKeys[e.keyCode];
    pressedKeys[e.keyCode] = true;
    switch (e.keyCode) {
        case !isRepeating && 39:
            // do something when the right arrow key is pressed, but not repeating
            break;
    }
}
function keyupHandler(e) {
    pressedkeys[e.keyCode] = false;
}

要停止您的 div 移动,您可以跟踪数组中的间隔 id,并在keyup事件期间使用类似的内容清除间隔clearInterval(intervalIds[e.keyCode]),但我可能会切换到使用setTimeout()并检查它们的键是否已按下。这样,您就不必跟踪另一个变量。

var pressedKeys = [];
function keydownHandler(e) {
    var isRepeating = !!pressedKeys[e.keyCode];
    pressedKeys[e.keyCode] = true;
    switch (e.keyCode) {
        case !isRepeating && 39:
            movFwr();
            break;
    }
}
function keyupHandler(e) {
    pressedkeys[e.keyCode] = false;
}
function movFwr() {
    if (pressedKeys[39] && currPos < 1000) {
        currPos += 10;
        a.style.left = currPos + "px";
        setTimeout(movFwr, 50);
    }
}

这样,当 div 到达右边缘时,您也会自动停止重复该功能,而不是等待用户释放箭头键。

于 2013-07-07T20:33:33.357 回答
0

跟踪最后按下的键,如果它与当前键相同,则返回忽略它,并用于clearInterval停止间隔

//global variables
var lastKey = 0;
var moveTimer = [];

//in keydown function
if(lastKey == keyPressed)
    return;
switch (keyPressed) {
    case 39:
        lastKey = keyPressed
        moveTimer[keyPressed] = setInterval(movFwr, 50);
        break;
}


//in a onkey up function
lastKey = null;
if(typeof(moveTimer[keyPressed]) != "undefined")
    clearInterval(moveTimer[keyPressed]);
于 2013-07-07T18:12:10.493 回答