Javascript onkeydown事件只开一次?

时间:2011-03-18 14:16:53

标签: javascript javascript-events

Heylo伙计们,

我希望onkeydown事件只触发一次函数。要再次触发该功能,用户必须释放该键并再次按下/按住。 我知道它相当简单,但我是JS新手。此外,我更喜欢避免使用jquery或其他库。 还有一件事,这应该适用于ie和firefox。

非常感谢!

7 个答案:

答案 0 :(得分:20)

你可以设置一个标志:

var fired = false;

element.onkeydown = function() {
    if(!fired) {
        fired = true;
        // do something
    }
};

element.onkeyup = function() {
    fired = false;
};

或取消绑定并重新绑定事件处理程序(可能更好):

function keyHandler() {
     this.onkeydown = null;
     // do something
}

element.onkeydown = keyHandler;

element.onkeyup = function() {
    this.onkeydown = keyHandler;
};

More information about "traditional" event handling.

您可能还希望使用addEventListenerattachEvent来绑定事件处理程序。有关详细信息,请查看quirksmode.org - Advanced event registration models

答案 1 :(得分:2)

你走了:

test.onkeydown = function() {
    if ( this.className === 'hold' ) { return false; }
    this.className = 'hold';

    // call your function here
};

test.onkeyup = function() {
    this.className = '';
};

现场演示: http://jsfiddle.net/simevidas/xAReL/2/

答案 2 :(得分:1)

以下是使用addEventListenerremoveEventListener

的方法
var textBox = document.getElementById("textBox");
function oneKeyDown(){
    $("body").append("<h1>KeyDown<h1>"); //just to show the keypress
    textBox.removeEventListener('keydown', oneKeyDown, false);
}
function bindKeyDown(){
  textBox.addEventListener('keydown', oneKeyDown, false);
}
textBox.addEventListener('keyup', bindKeyDown, false)   
bindKeyDown();

jsfiddle上的代码示例。

请注意,对于IE,您需要使用attachEvent, detachEvent

答案 3 :(得分:0)

JQuery的one会帮助你。

它的作用是将eventHandler绑定到event,当事件发生时,它运行eventHandler并解除绑定,以便它不会在下一个事件中触发。

答案 4 :(得分:0)

如其他答案中所述,没有'onkeyfirstdown'或类似的事件可供收听。

最好的解决方案是跟踪js-object中已经关闭的键:

var keysdown = {};

element.addEventListener('keydown', function(evt) {
  if(!(evt.key in keysdown)) {
    keysdown[evt.key] = true;
    // key first pressed
  }
});

element.addEventListener('keyup', function(evt) {
  delete keysdown[evt.key];
});

这样,如果按下多个键,您将不会跳过'keyfirstpressed'事件。

(此处发布的许多其他解决方案只会在没有其他密钥关闭时触发。)

答案 5 :(得分:0)

有一次&#34;一次&#34;您可以使用的参数

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

例如:

element.addEventListener('keyup', function(event) {  
    doSomething()
}, {once: true});

一旦被呼叫,它就会将其删除。

如果它是命名函数

,您也可以使用removeEventListener

答案 6 :(得分:0)

这是我的解决方案,仅当在目标上第一个按下键(例如window或某个input字段)时,该函数才运行您传递的函数。如果用户要再次触发键,则必须释放并再次按下。


香草JS

const onKeyPress = (func, target = window) => {
  // persistent "store" to track what keys are being pressed
  let pressed = {};

  // whenever a keydown event is fired ontarget element
  const onKeyDown = (event) => {
    // if key isn't already pressed, run func
    if (!pressed[event.which])
      func(event);

    // add key to store
    pressed = { ...pressed, [event.which]: true };
  };

  // whenever a keyup event is fired on the window element
  const onKeyUp = (event) => {
    const { [event.which]: id, ...rest } = pressed;
    // remove key from store
    pressed = rest;
  };

  // add listeners
  target.addEventListener('keydown', onKeyDown);
  window.addEventListener('keyup', onKeyUp);

  // return a function that can be called to remove listeners
  return () => {
    target.removeEventListener('keydown', onKeyDown);
    window.removeEventListener('keyup', onKeyUp);
  };
};

然后使用它:

const removeListener = onKeyPress((event) => console.log(event.which + ' key pressed'))

removeListener(); // when you want to remove listeners later

反应和反应挂钩

import { useState } from 'react';
import { useEffect } from 'react';
import { useCallback } from 'react';

export const useKeyPress = (func, target = window) => {
  // persistent "store" to track what keys are being pressed
  const [pressed, setPressed] = useState({});

  // whenever a keydown event is fired ontarget element
  const onKeyDown = useCallback(
    (event) => {
      // if key isn't already pressed, run func
      if (!pressed[event.which])
        func(event);

      // add key to store
      setPressed({ ...pressed, [event.which]: true });
    },
    [func, pressed]
  );

  // whenever a keyup event is fired on the window element
  const onKeyUp = useCallback((event) => {
    // remove key from store
    const { [event.which]: id, ...rest } = pressed;
    setPressed(rest);
  }, [pressed]);

  useEffect(() => {
    // add listeners when component mounts/changes
    target.addEventListener('keydown', onKeyDown);
    window.addEventListener('keyup', onKeyUp);

    // cleanup/remove listeners when component unmounts/changes
    return () => {
      target.removeEventListener('keydown', onKeyDown);
      window.removeEventListener('keyup', onKeyUp);
    };
  }, [target, onKeyDown, onKeyUp]);
};

然后使用它:

import { useKeyPress } from 'wherever';

useKeyPress((event) => console.log(event.which + ' key pressed'))