有没有办法检测JavaScript当前是否存在关键字?
我知道“keydown”事件,但这不是我需要的。按下键后的一段时间,我希望能够检测到它是否仍被按下。
P上。 S.最大的问题似乎是,在一段时间后,密钥开始重复,启动keydown和keyup事件,如恶魔。希望只有一个简单的isKeyDown(key)函数,但如果没有,则需要克服/解决这个问题。
答案 0 :(得分:113)
除了使用keyup
和keydown
侦听器来跟踪密钥何时关闭和备份之外, 实际上还有一些属性可以告诉您某些密钥是否已关闭
window.onmousemove = function (e) {
if (!e) e = window.event;
if (e.shiftKey) {/*shift is down*/}
if (e.altKey) {/*alt is down*/}
if (e.ctrlKey) {/*ctrl is down*/}
if (e.metaKey) {/*cmd is down*/}
}
这适用于所有浏览器生成的事件对象,例如来自keydown
,keyup
和keypress
的事件对象,因此您不必使用mousemove。
我尝试使用document.createEvent('KeyboardEvent')
和document.createEvent('KeyboardEvent')
生成我自己的事件对象并寻找e.shiftKey
等等,但我没有运气。
我在Mac上使用Chrome 17
答案 1 :(得分:59)
有没有办法检测JavaScript当前是否存在关键字?
不。唯一的可能是监控每个keyup
和keydown
并记住。
经过一段时间后,密钥开始重复,启动keydown和keyup事件,如恶魔。
不应该。您肯定会重复keypress
,在许多浏览器中,您也会重复keydown
,但如果keyup
重复,那就是错误。
不幸的是,这不是一个完全闻所未闻的错误:在Linux,Chromium和Firefox上(当它在GTK +下运行时,它在流行的发行版中,如Ubuntu)都会生成重复的keyup-keypress-keydown序列持有钥匙,这是不可能与某人快速敲击钥匙的区别。
答案 2 :(得分:33)
我的解决方案:
var keys = {};
window.onkeyup = function(e) { keys[e.keyCode] = false; }
window.onkeydown = function(e) { keys[e.keyCode] = true; }
我现在可以通过检查
来检查脚本中的任何其他位置是否按下了任何键keys["code of the key"]
如果是,则按下该键。
答案 3 :(得分:11)
我不相信有任何像isKeyDown函数,但你可以自己编写。
基本上,创建一个数组,其长度是您要监视的键数。然后使用documents / pages / controls keyUp和keyDown事件,使用该键的状态更新数组。
然后编写一个函数,检查某个键是否关闭并返回一个bool。
var keyEnum = { W_Key:0, A_Key:1, S_Key:2, D_Key:3 };
var keyArray = new Array(4);
function onKeyDown()
{
// Detect which key was pressed
if( key == 'w' )
keyArray[keyEnum.W_Key] = true;
// Repeat for each key you care about...
}
function onKeyUp()
{
// Detect which key was released
if( key == 'w' )
keyArray[keyEnum.W_Key] = false;
// Repeat for each key you care about...
}
function isKeyDown(key)
{
return keyArray[key];
}
这应该能达到你想要的效果。
答案 4 :(得分:1)
其他人之前已经提出过这样的问题(虽然我现在没有看到任何明显的愚蠢行为)。
我认为答案是keydown
事件(及其双keyup
)是您获得的所有信息。重复操作非常牢固地连接到操作系统,并且应用程序没有太多机会向BIOS查询密钥的实际状态。
如果你需要让这个工作,你可以做什么,也许还有,就是以编程方式去除反弹键。从本质上讲,您可以自己评估keydown
和keyup
但忽略keyup
事件,如果它在上一次keydown
之后过快发生......或者基本上,您应该推迟对keyup
的响应时间足够长,以确保在keydown
的0.25秒之后没有其他keyup
事件。
这将涉及使用计时器活动,并记录先前事件的毫秒时间。我不能说这是一个非常有吸引力的解决方案,但是......
答案 5 :(得分:1)
/*
Tracks what keys are currently down on the keyboard
*/
function keyboard_module(onUpdate){
var kb = {};
var unicode_mapping = {};
document.onkeydown = function(e){
var unicode=e.charCode? e.charCode : e.keyCode
var key = getKey(unicode);
kb[key] = true;
if(onUpdate){
onUpdate(kb);
}
}
document.onkeyup = function(e){
var unicode=e.charCode? e.charCode : e.keyCode
var key = getKey(unicode);
delete kb[key];
if(onUpdate){
onUpdate(kb);
}
}
function getKey(unicode){
if(unicode_mapping[unicode]){
var key = unicode_mapping[unicode];
}else{
var key= unicode_mapping[unicode] = String.fromCharCode(unicode);
}
return key;
}
return kb;
}
function testing(kb){
console.log('These are the down keys', kb);
}
var keyboard = keyboard_module(testing);
....
//somewhere else in the code
if(keyboard['K']){/*do something special */}
答案 6 :(得分:1)
结束此处以检查浏览器是否已内置了某些内容,但似乎没有。这是我的解决方案(非常类似于罗伯特的回答):
"use strict";
let is_key_down = (() => {
let state = {};
window.addEventListener('keyup', (e) => state[e.key] = false);
window.addEventListener('keydown', (e) => state[e.key] = true);
return (key) => state.hasOwnProperty(key) && state[key] || false;
})();
然后,您可以使用is_key_down('ArrowLeft')
检查是否按下了某个键。
答案 7 :(得分:0)
答案 8 :(得分:0)
我知道这是一个非常古老的问题,但是有一个非常轻量级的(〜.5Kb)JavaScript库可以有效地“修补”使用DOM API时键盘事件处理程序的不一致触发。
图书馆是Keydrown。
这是一个操作代码示例,只需更改设置侦听器的键,就可以很好地满足我的目的:
kd.P.down(function () {
console.log('The "P" key is being held down!');
});
kd.P.up(function () {
console.clear();
});
// This update loop is the heartbeat of Keydrown
kd.run(function () {
kd.tick();
});
我已将Keydrown整合到我的客户端JavaScript中,以便在我正在编写的红灯绿灯游戏中获得适当的暂停动画。您可以查看整个游戏here。 (注意:如果您将来阅读此内容,游戏应该是代码完整且可玩的:-D!)
我希望这会有所帮助。
答案 9 :(得分:0)
我查看了以上答案,并且提出的keydown
/ keyup
方法仅在特殊情况下有效。如果用户alt跳开标签,或使用键盘手势打开新的浏览器窗口或标签,则将注册keydown
,这很好,因为此时无法确定该密钥是否是某些东西。该Web应用正在监视,或者是标准的浏览器或操作系统快捷方式。回到浏览器页面,尽管它是同时释放的,但仍然会认为该键已被按住。或者,只是在用户使用鼠标切换到另一个选项卡或应用程序,然后将其释放到我们的页面之外时简单地按住某些键即可。
可以通过Shift
等监视修饰键(mousemove
等),假设在回跳时至少需要一个鼠标交互,这是常见的情况。
对于大多数所有其他键(修饰符Tab
,Delete
,但包括Space
,Enter
),监视keypress
适用于大多数应用程序-按住的键将继续发射。不过,由于keypress
触发的周期性,重置密钥会有一些延迟。基本上,如果keypress
不保持触发状态,则可以排除大多数键。尽管我还没有探索如何处理Tab
和Backspace
,但将其与修饰符结合起来还是很密封的。
我敢肯定,有一个库可以针对此DOM弱点进行抽象,或者可能是某些DOM标准更改解决了这个问题,因为这是一个相当老的问题。
答案 10 :(得分:0)
这在Firefox和Chrome中有效。
我需要在本地打开一个特殊的html文件(在Windows的文件浏览器中选择该文件时,通过按Enter
),或者只是为了查看文件,或者是在特殊的在线编辑器中对其进行编辑
因此,我想通过按住Ctrl
的同时按住Enter
键来区分这两个选项。
正如大家从这里的所有答案中都了解到的那样,这似乎不太可能,但这是一种以我可以接受的方式模仿这种行为的方式。
工作方式如下:
如果您在打开文件时按住Ctrl
键,那么keydown事件将永远不会在javascript代码中触发。但是会触发一个keyup事件(当您最终释放Ctrl
键时)。该代码捕获了这一点。
一旦其中一个事件发生,代码也将关闭键盘事件(键盘事件和键盘事件)。因此,如果在文件打开后按Ctrl
键,则不会发生任何事情。
window.onkeyup = up;
window.onkeydown = down;
function up(e) {
if (e.key === 'F5') return; // if you want this to work also on reload with F5.
window.onkeyup = null;
window.onkeyup = null;
if (e.key === 'Control') {
alert('Control key was released. You must have held it down while opening the file, so we will now load the file into the editor.');
}
}
function down() {
window.onkeyup = null;
window.onkeyup = null;
}
答案 11 :(得分:-1)
我知道为时已晚,但我有一个轻量级(398 字节)脚本,该脚本在按下某个键时返回:https://github.com/brunoinds/isKeyPressed
if (KeyPressing.isKeyPressed(13)){ //Pass the keyCode integer as parameter
console.log('The Enter key is being pressed!')
}else{
console.log('The Enter key is NOT being pressed!')
}
你甚至可以设置一个时间间隔来检查按键是否被按下:
setInterval(() => {
if (KeyPressing.isKeyPressed(13)){
console.log('The Enter key is being pressed!')
}else{
console.log('The Enter key is NOT being pressed!')
}
}, 1000) //Update data every 1000ms (1 second)
答案 12 :(得分:-2)
$('#mytextbox').keydown(function (e) {
if (e.keyCode == 13) {
if (e.altKey) {
alert("alt is pressed");
}
}
});
如果按alt + Enter,您将看到警报。