Javascript 按下键盘键时的JS功能?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14261062/
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
JS function when keyboard key is pressed?
提问by tkbx
Is there a way to run a JavaScript function when a key is pressed and released?
有没有办法在按下和释放键时运行 JavaScript 函数?
For example, how would I run a function example()when the Tkey is pressed? I've seen examples of these before, but they were long and messy, and I couldn't get them to work. Would something like this just go in a <script>in the <head>?
例如,example()当T按键被按下时我将如何运行一个函数?我以前见过这样的例子,但它们又长又乱,我无法让它们工作。将这样的事情只是走了<script>的<head>?
回答by jcolebrand
Part 1: Where to put the scriptblock?
第 1 部分:将脚本块放在哪里?
To capture over the entire page, like as a page-help-function (maybe you want to capture F1?) then you would put your script block in the <head>tag, inside a script. But if you want to capture a DOM element, then you have to execute the code after the DOM element occurs (because the script is interpreted as it's found, if the DOM element doesn't exist yet, the selector engine can't find it. If this doesn't make sense say something, and an article shall be found).
要捕获整个页面,例如作为页面帮助功能(也许您想捕获 F1?),那么您可以将脚本块放在<head>标记中,在脚本内。但是如果你想捕获一个DOM元素,那么你必须在DOM元素出现后执行代码(因为脚本被解释为找到了,如果DOM元素还不存在,选择器引擎找不到它. 如果这没有意义,请说些什么,然后会找到一篇文章)。
But here's something for you to consider: Good javascript programmer mentors today recommend all javascript be loaded at the end of the page. The only things you mightwant to load at the head of the document are libraries like jQuery, because those are widely cached, especially if you're using a CDN version of jQuery, as that generally tends to not impact load times.
但是这里有一些事情需要你考虑:今天优秀的 javascript 程序员导师推荐所有的 javascript 都在页面的末尾加载。您可能希望在文档开头加载的唯一内容是 jQuery 之类的库,因为它们被广泛缓存,特别是如果您使用的是 jQuery 的 CDN 版本,因为这通常不会影响加载时间。
So that answers the question of "where do I put the codeblock, in the <head>?": No. At the end.
所以这就回答了“我应该把代码块放在哪里<head>?”的问题:不。最后。
Now, as to how to actually capture the keystroke, let's do it in three parts:
现在,至于如何实际捕获击键,让我们分三个部分进行:
Part 2: Capturing all keyboard events on the window:
第 2 部分:捕获窗口上的所有键盘事件:
<html>
<head>
<title>blah blah</title>
<meta "woot, yay StackOverflow!">
</head>
<body>
<h1>all the headers</h1>
<div>all the divs</div>
<footer>All the ... ... footers?</footer>
<script>
/* the last example replaces this one */
function keyListener(event){
//whatever we want to do goes in this block
event = event || window.event; //capture the event, and ensure we have an event
var key = event.key || event.which || event.keyCode; //find the key that was pressed
//MDN is better at this: https://developer.mozilla.org/en-US/docs/DOM/event.which
if(key===84){ //this is for 'T'
doThing();
}
}
/* the last example replace this one */
var el = window; //we identify the element we want to target a listener on
//remember IE can't capture on the window before IE9 on keypress.
var eventName = 'keypress'; //know which one you want, this page helps you figure that out: http://www.quirksmode.org/dom/events/keys.html
//and here's another good reference page: http://unixpapa.com/js/key.html
//because you are looking to capture for things that produce a character
//you want the keypress event.
//we are looking to bind for IE or non-IE,
//so we have to test if .addEventListener is supported,
//and if not, assume we are on IE.
//If neither exists, you're screwed, but we didn't cover that in the else case.
if (el.addEventListener) {
el.addEventListener('click', keyListener, false);
} else if (el.attachEvent) {
el.attachEvent('on'+eventName, keyListener);
}
//and at this point you're done with registering the function, happy monitoring
</script>
</body>
</html>
Part 3: Capturing all keyboard events on a specific element
第 3 部分:捕获特定元素上的所有键盘事件
This line: var el = window; //we identify the element we want to target a listener onmight also be var el = document.getElementByTagName('input');or some other document selector. The example still works the same that way.
这一行:var el = window; //we identify the element we want to target a listener on也可能是var el = document.getElementByTagName('input');或其他一些文档选择器。该示例仍然以同样的方式工作。
Part 4: An 'elegant' solution
第 4 部分:“优雅”的解决方案
var KeypressFunctions = [];
KeypressFunctions['T'.charCodeAt(0)] = function _keypressT() {
//do something specific for T
}
KeypressFunctions['t'.charCodeAt(0)] = function _keypresst() {
//do something specific for t
}
//you get the idea here
function keyListener(event){
//whatever we want to do goes in this block
event = event || window.event; //capture the event, and ensure we have an event
var key = event.key || event.which || event.keyCode; //find the key that was pressed
//MDN is better at this: https://developer.mozilla.org/en-US/docs/DOM/event.which
KeypressFunctions[key].call(); //if there's a defined function, run it, otherwise don't
//I also used .call() so you could supply some parameters if you wanted, or bind it to a specific element, but that's up to you.
}
What does all this do?
这一切有什么作用?
The KeypressFunctionsis an array, that we can populate with various values but have them be somewhat human readable. Each index into the array is done as 'T'.charCodeAt(0)which gives the character code (event.which || event.keyCodelook familiar?) for the index position into the array that we're adding a function for. So in this case our array only has two defined index-values, 84(T) and 116(t). We could've written that as KeypressFunctions[84] = function ...but that's less human-readable, at the expense of the human-readable is longer. Always write code for yourself first, the machine is often smarter than you give it credit for. Don't try and beat it with logic, but don't code excessive if-else blocks when you can be slightly elegant.
这KeypressFunctions是一个数组,我们可以用各种值填充它,但让它们在某种程度上是人类可读的。数组中的每个索引都完成了,因为'T'.charCodeAt(0)它给出了event.which || event.keyCode我们为其添加函数的数组中索引位置的字符代码(看起来很熟悉?)。所以在这种情况下,我们的数组只有两个定义的索引值,84(T) 和116(t)。我们可以这样写,KeypressFunctions[84] = function ...但那是人类可读性较低,代价是人类可读性更长。始终先为自己编写代码,机器通常比您认为的更聪明。不要试图用逻辑来击败它,但是当你可以稍微优雅时不要编写过多的 if-else 块。
gah! I forgot to explain something else!
The reason for the _keypressTand _keypresstis so that when this gets called as an anonymous function, or as part of a callstack (it will, one day) then you can identify the function. This is a really handy practice to get into the habit of, making sure that all potentially anonymous functions still get "named" even though they have a proper name elsewhere. Once again, good javascript mentors suggest things that help folks ;-).
gah! I forgot to explain something else!
呸!我忘了解释别的东西!
究其原因,_keypressT和_keypresst是这样,当这个被称为匿名函数,或作为一个调用堆栈的一部分(会,一天),那么你可以识别功能。这是养成习惯的非常方便的做法,确保所有潜在的匿名函数仍然被“命名”,即使它们在别处有一个适当的名称。再一次,优秀的 javascript 导师会建议可以帮助人们的东西 ;-)。
呸!我忘了解释别的东西!
Notice you could just as easily do:
请注意,您可以轻松地执行以下操作:
function doThing() //some pre-defined function before our code
var KeypressFunctions = [];
KeypressFunctions['T'.charCodeAt(0)] = doThing
KeypressFunctions['t'.charCodeAt(0)] = doThing
and then for either T or t, the doThing function is run. Notice that we just passed the name of the function and we didn't try to runthe function by doThing()(this is a HUGE difference and a big hint if you're going to do this sort of thing)
然后对于 T 或 t,运行 doThing 函数。请注意,我们只是传递了函数的名称,我们并没有尝试运行该函数doThing()(这是一个巨大的差异,如果您要执行此类操作,这是一个很大的提示)
I can't believe I forgot this one!
我不敢相信我忘记了这个!
Part 5: jQuery:
第 5 部分:jQuery:
Because the emphasis today is on jQuery, here's a block you can put anywhere in your app after the jQuery library has loaded (head, body, footer, whatever):
因为今天的重点是 jQuery,所以在加载 jQuery 库后,您可以将一个块放在应用程序中的任何位置(head、body、footer,等等):
<script>
function doTheThingsOnKeypress(event){
//do things here! We've covered this before, but this time it's simplified
KeypressFunctions[event.which].call();
}
$(document).on('keypress','selector',doTheThingsOnKeypress);
// you could even pass arbitrary data to the keypress handler, if you wanted:
$(document).on('keypress','selector',{/* arbitrary object here! */},doTheThingsOnKeypress);
//this object is accessible through the event as data: event.data
</script>
If you're going to use the KeypressFunctionsas from before, ensure they are actually defined before this.
如果您要使用KeypressFunctions之前的 ,请确保在此之前实际定义了它们。
回答by Danilo Valente
Use the onkeydownevent and the keyCodeproperty (where Tcode is 84):
使用onkeydown事件和keyCode属性(其中T代码为 84):
document.onkeydown = function(e){
e = e || window.event;
var key = e.which || e.keyCode;
if(key===84){
example();
}
}
I just suggest you to use addEventListener/attachEventmethods instead of the onkeydownproperty
我只是建议你使用addEventListener/attachEvent方法而不是onkeydown属性
EDIT:As T.J. Crowder requested, here's the addEventListener/attachEventusage, with a compatibility check:
编辑:正如 TJ Crowder 所要求的,这里是addEventListener/attachEvent用法,并进行了兼容性检查:
var addEvent = document.addEventListener ? function(target,type,action){
if(target){
target.addEventListener(type,action,false);
}
} : function(target,type,action){
if(target){
target.attachEvent('on' + type,action,false);
}
}
addEvent(document,'keydown',function(e){
e = e || window.event;
var key = e.which || e.keyCode;
if(key===84){
example();
}
});
And for a list of the key codes, check this page
有关关键代码的列表,请查看此页面
回答by Quentin
- Bind a keyup/down/pressevent handlerto the
documentobject. - Check which key was pressed (by looking at
keyorkeyCodeon the event object - Call the function if it matches the key want you want
It doesn't matter where the script runs, the documentobject is (effectively) always available.
脚本在何处运行无关紧要,document对象(有效地)始终可用。

