将document.onkeydown限制为每秒一次

时间:2018-03-10 08:47:51

标签: javascript handler restriction onkeydown

我想知道是否有办法将document.onkeydown限制为每1000毫秒(1秒)一次。

这是我的代码:

document.onkeydown = function(e) {
    switch (e.keyCode) {
        case 37:
            console.log("left");
            break;
        case 38:
            console.log("up");
            break;
        case 39:
            console.log("right");
            break;
        case 40:
            console.log("down");
            break;
    }
};

因此,如果用户点击向下箭头(case 40),它会将down打印到控制台。

我想知道我是否可以限制它,所以如果用户在一秒内多次点击向下箭头,它只会注册一次,并且不会排队。

3 个答案:

答案 0 :(得分:1)

试试这个:

function debounce (fn, delay) {
    var timer = null;

    return function () {
        var context = this, args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function () {
            fn.apply(context, args);
        }, delay);
    };
};

document.onkeydown = debounce(function(e) {
    switch (e.keyCode) {
        case 37:
            console.log("left");
            break;
        case 38:
            console.log("up");
            break;
        case 39:
            console.log("right");
            break;
        case 40:
            console.log("down");
            break;
    }
}, 1000);

UPDATE(在控制台写入密钥之前删除1s延迟):

function debounce (fn, delay) {
    var timer = null;
    var during = null;

    return function () {

        var context = this, args = arguments;
        if(!during) {
           fn.apply(context, args);
           during = 1;
        }

        clearTimeout(timer);
        timer = setTimeout(function () {
            during = null;
        }, delay); 

    };
};

更新2(当用户长时间按键,然后每隔一秒控制台写一次密钥)

function debounce (fn, delay) {
    var timer = null;
    var start = + new Date(); // Unix timestamp

    return function () {
        var current = + new Date();

        if(current-start > delay) {
           fn.apply(this, arguments);
           start = current;
        }
    };
};

工作小提琴HERE

答案 1 :(得分:1)

我会做这样的事情,

document.onkeydown = function(e) {
    let lastEvent = null,
        lastPressesTimestapm = null
    if(e.keyCode === lastEvent && lastPressesTimestapm && Date.now() - lastPressesTimestapm < 1000){
        break
    } else{
        lastEvent = e.keyCode, lastPressesTimestapm = Date.now()
    }
    switch (e.keyCode) {
        case 37:
            console.log("left");
            break;
        case 38:
            console.log("up");
            break;
        case 39:
            console.log("right");
            break;
        case 40:
            console.log("down");
            break;
    }
};

答案 2 :(得分:0)

关于这个主题的一个很好的问题,有一个非常有用的答案和许多与JavaScript相关的有用链接,可以在Difference Between throttling and debouncing a function的SO找到。

有许多完善的库,例如underscorelodash,可以很好地处理throttle和/或debounce

如果有一个Function.prototype based implementation of throttle / debounce OP的工作解决方案可能看起来像这样......

&#13;
&#13;
// example code

function logKeyDown(evt) {
  var
    keyCode = evt.keyCode,
    value   = {

      37: 'left',
      38: 'up',
      39: 'right',
      40: 'down'

    }[keyCode] || keyCode;

  console.log("logKeyDown : ", value);
}

var keyEventHandler = logKeyDown.throttle(1000);



// UI helper code

function registerKeyLogger() {
  elmRegister.disabled    = true;
  elmDeregister.disabled  = false;

  window.addEventListener("keydown", keyEventHandler, false);

  console.log('\n');
  console.log('+++ keylogger registered +++');
  console.log('+++ press any key - inspect log +++');
}
function deregisterKeyLogger() {
  elmRegister.disabled    = false;
  elmDeregister.disabled  = true;

  window.removeEventListener("keydown", keyEventHandler);

  console.log('\n');
  console.log('+++ key-logger has been deregistered +++');
}

var
  elmRegister   = document.getElementById('register-key-logger'),
  elmDeregister = document.getElementById('deregister-key-logger');

if (elmRegister && elmDeregister) {
  elmRegister.disabled = false;
  elmRegister.addEventListener('click', registerKeyLogger);
  elmDeregister.addEventListener('click', deregisterKeyLogger);
}
&#13;
.as-console-wrapper { max-height: 100%!important; top: 40px; }
&#13;
<script>(function(b,w,p,h){h=h.prototype;var q=function(a){return"function"==typeof a&&"function"==typeof a.call&&"function"==typeof a.apply},x=b.isFinite,y=b.parseInt,k=b.setTimeout,r=b.clearTimeout,z=q(p.now)&&p.now||function(){return(new p).getTime()},t=w.max,v=function(a){return x(a=y(a,10))&&a||0};h.throttle=function(a,u,d){d=null!=d&&d||null;a=t(v(a),0)||200;u=!!u;var e=this,l,c,f,g,b,m,n=function(){f=g;e.apply(b,m)};return q(e)&&function(){r(l);b=d||this;m=arguments;g=z();f?(c=g-f,u?c>=a&&n():l=k(n,t(a-c,0))):n()}||e};h.debounce=function(a,b,d){d=null!=d&&d||null;a=t(v(a),0)||100;b=!!b;var e=this,l,c,f,g,h=function(){c=null},m=function(){c=null;e.apply(f,g)},n=function(){l=k(h,a);e.apply(f,g)};c=null;return q(e)&&function(){f=d||this;g=arguments;c?(r(l),r(c),c=k(m,a)):c=b?k(n,0):k(m,a)}||e}})(window||global||this,Math,Date,Function);</script>

<button id="register-key-logger" disabled="disabled">register key logger</button>
<button id="deregister-key-logger" disabled="disabled">deregister key logger</button>
&#13;
&#13;
&#13;