8

有没有办法在按下和释放键时运行 JavaScript 函数?

例如,按下键example()时如何运行函数?T我以前见过这样的例子,但它们又长又乱,我无法让它们工作。像这样的东西会放在里面<script><head>

4

3 回答 3

25

第 1 部分:将脚本块放在哪里?

要捕获整个页面,例如作为页面帮助功能(也许您想捕获 F1?),那么您可以将脚本块放在<head>标记中,在脚本内。但是如果你想捕获一个DOM元素,那么你必须在DOM元素发生后执行代码(因为脚本被解释为找到了,如果DOM元素还不存在,则选择器引擎找不到它.如果这没有意义,说点什么,应该找到一篇文章)。

但这里有一些事情需要您考虑:今天优秀的 javascript 程序员导师建议将所有 javascript 加载到页面末尾。您可能希望在文档开头加载的唯一内容是 jQuery 之类的库,因为它们被广泛缓存,特别是如果您使用的是 jQuery 的 CDN 版本,因为这通常不会影响加载时间。

所以这就回答了“我应该把代码块放在哪里<head>?”的问题:不,最后。

现在,关于如何实际捕捉击键,让我们分三个部分来做:

第 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>

第 3 部分:捕获特定元素上的所有键盘事件

这一行:var el = window; //we identify the element we want to target a listener on也可能是var el = document.getElementByTagName('input');或其他一些文档选择器。该示例仍然以这种方式工作。

第 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.
}

这一切有什么作用?

KeypressFunctions是一个数组,我们可以填充各种值,但让它们在某种程度上是人类可读的。数组中的每个索引都是这样完成的,它给出了我们为其添加函数的数组中索引位置'T'.charCodeAt(0)的字符代码(看起来很熟悉?)。event.which || event.keyCode所以在这种情况下,我们的数组只有两个定义的索引值,84(T) 和116(t)。我们本可以这样写,KeypressFunctions[84] = function ...但人类可读性较差,代价是人类可读性更长。始终首先为自己编写代码,这台机器通常比你想象的要聪明。不要试图用逻辑打败它,但是当你可以稍微优雅时不要编写过多的 if-else 块。

啊!我忘了解释别的!and
的原因是,当它作为匿名函数或作为调用堆栈的一部分(有一天会)被调用时,您可以识别该函数。这是一个非常方便的习惯,可以确保所有潜在的匿名函数仍然被“命名”,即使它们在其他地方有一个专有名称。再一次,优秀的 javascript 导师会提出对人们有帮助的建议;-)。啊!我忘了解释别的!_keypressT_keypresst

请注意,您可以轻松地执行以下操作:

function doThing() //some pre-defined function before our code

var KeypressFunctions = [];
KeypressFunctions['T'.charCodeAt(0)] = doThing
KeypressFunctions['t'.charCodeAt(0)] = doThing

然后对于 T 或 t,运行 doThing 函数。请注意,我们只是传递了函数的名称,并没有尝试运行函数doThing()(这是一个巨大的差异,如果你要做这种事情,这是一个很大的提示)


我不敢相信我忘记了这个!

第 5 部分:jQuery:

因为今天的重点是 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>

如果您要KeypressFunctions像以前一样使用,请确保在此之前实际定义它们。

于 2013-01-10T16:09:43.897 回答
9

使用onkeydown事件和keyCode属性(其中T代码为 84):

document.onkeydown = function(e){
    e = e || window.event;
    var key = e.which || e.keyCode;
    if(key===84){
        example();
    }
}

我只是建议你使用addEventListener/attachEvent方法而不是onkeydown属性

编辑: 根据 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();
    }
});

有关关键代码的列表,请查看此页面

于 2013-01-10T15:17:54.750 回答
2
  1. 将keyup/down/press 事件处理程序绑定到document对象。
  2. 检查按下了哪个键(通过查看keykeyCode事件对象上
  3. 如果它与您想要的键匹配,则调用该函数

脚本在哪里运行并不重要,document对象(有效地)始终可用。

于 2013-01-10T15:15:19.870 回答