Javascript onkeydown 事件只触发一次?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5353254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript onkeydown event fire only once?
提问by WindowsMaker
I want to have a onkeydown
event fire a function only once. for that function to fire again, the user has to release the key and press/hold again.
I know its fairly simple but I'm new at JS. Also I prefer to avoid using jQuery or other libs.
One more thing, this should work for both ie and firefox.
我想让一个onkeydown
事件只触发一次函数。要再次触发该功能,用户必须松开按键并再次按住/按住。我知道它相当简单,但我是 JS 的新手。另外我更喜欢避免使用 jQuery 或其他库。还有一件事,这应该适用于 ie 和 firefox。
回答by Felix Kling
You could set a flag:
你可以设置一个标志:
var fired = false;
element.onkeydown = function() {
if(!fired) {
fired = true;
// do something
}
};
element.onkeyup = function() {
fired = false;
};
Or unbind and rebind the event handler (might be better):
或者取消绑定并重新绑定事件处理程序(可能更好):
function keyHandler() {
this.onkeydown = null;
// do something
}
element.onkeydown = keyHandler;
element.onkeyup = function() {
this.onkeydown = keyHandler;
};
More information about "traditional" event handling.
You might also want to use addEventListener
and attachEvent
to bind the event handlers. For more information about that, have a look at quirksmode.org - Advanced event registration models.
您可能还想使用addEventListener
和attachEvent
绑定事件处理程序。有关更多信息,请查看quirksmode.org - 高级事件注册模型。
回答by ?ime Vidas
Here you go:
干得好:
test.onkeydown = function() {
if ( this.className === 'hold' ) { return false; }
this.className = 'hold';
// call your function here
};
test.onkeyup = function() {
this.className = '';
};
Live demo:http://jsfiddle.net/simevidas/xAReL/2/
回答by Mark Coleman
Here is a method that uses addEventListener
and removeEventListener
这是一种使用addEventListener
和的方法removeEventListener
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();
Code example on jsfiddle.
jsfiddle上的代码示例。
One note, for IE you will need to use attachEvent
, detachEvent
.
请注意,对于 IE,您需要使用attachEvent
,detachEvent
。
回答by josh
as stated in the other answers, there is no 'onkeyfirstdown' or similar event to listen for.
正如其他答案中所述,没有“onkeyfirstdown”或类似的事件可以监听。
the best solution is to keep track of which keys are already down in a js-object:
最好的解决方案是跟踪 js 对象中哪些键已经关闭:
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];
});
this way, you will not be skipping 'keyfirstpressed' events if more than one key is held down.
这样,如果按住多个键,您将不会跳过“keyfirstpressed”事件。
(many of the other solutions posted here will only fire when no other keys are down).
(此处发布的许多其他解决方案仅在没有其他键按下时才会触发)。
回答by Alistair R
There's a "once" parameter you can use
您可以使用“一次”参数
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
Eg:
例如:
element.addEventListener('keyup', function(event) {
doSomething()
}, {once: true});
It'll remove it as soon as it's been called.
它会在调用后立即将其删除。
Alternatively you can use removeEventListener
if it's a named function
或者,removeEventListener
如果它是命名函数,您可以使用
回答by V. Rubinetti
Here is my solution that will only run the function you pass it when a key is FIRST pressed on the target (eg window
or some input
field). If the user wants to trigger a key again, they'll have to release it and press it again.
这是我的解决方案,它只会在目标(例如window
或某个input
字段)上第一次按下键时运行您传递给它的函数。如果用户想再次触发一个键,他们必须松开它并再次按下它。
Vanilla JS
香草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);
};
};
And then to use it:
然后使用它:
const removeListener = onKeyPress((event) => console.log(event.which + ' key pressed'))
removeListener(); // when you want to remove listeners later
React and React Hooks
反应和反应钩子
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]);
};
And then to use it:
然后使用它:
import { useKeyPress } from 'wherever';
useKeyPress((event) => console.log(event.which + ' key pressed'))