Как отключить повторяющийся keydown в JavaScript [дубликат]

этот вопрос уже есть ответ здесь:

у меня такая же проблема, как у этого парня Как отключить повторяющийся keydown в jQuery, просто я не использую jQuery, поэтому мне трудно переводя его на" чистый " JavaScript, в любом случае я установил switch - случай некоторых клавиш, и когда я нажимаю и удерживаю клавишу со стрелкой вправо, мой div летит. Также, если это не проблема, можете ли вы сказать мне, что было бы самым простым способом остановить движение div, когда я отпущу клавишу со стрелкой вправо, мне нужно сделать новый корпус переключателя с clearInterval или?

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 ответов


что-то вроде этого должно сделать трюк;

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

    // your magic code here
}, false);

document.addEventListener('keyup', function () {
    down = false;
}, false);

отслеживайте последнюю нажатую клавишу, если она такая же, как текущая, игнорируйте ее, возвращаясь, и используйте 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]);

Я бы записал время и предотвратил действие, если не прошло достаточно времени, например, используя 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

чтобы игнорировать ключевые события, вызванные повторами клавиш, следите за тем, какие клавиши нажимаются во время 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, вы можете отслеживать идентификаторы интервалов в массиве и очищать интервал во время 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 достигнет правого края, вместо того, чтобы ждать, пока пользователь отпустит клавишу со стрелкой.