共计 1899 个字符,预计需要花费 5 分钟才能阅读完成。
最近在开发过程中遇到了一个问题,感觉能够通过监听 keydown 事件来解决。然而,在实际的过程中发现,我原先对于 keydown 事件的了解并不是很正确。所以,在具体理解过 keydown 事件之后,在此做个总结。
本文次要包含以下几个方面的内容:
- 遇到的问题
- keydown 事件
- 解决方案
遇到的问题
在开发过程中,我遇到这样一个需要:
当鼠标悬浮在指标 dom 上的时候,鼠标须要设置成非凡的款式:
- 没有按住 ctrl 键,鼠标款式设置成款式 1;
- 按住 ctrl 键,鼠标款式设置成款式 2。
我的第一想法是,通过监听 mousemove 事件来判断鼠标是否悬浮在指标 dom 上。而后通过 event.ctrlKey 来判断此时是否按住了 ctrl 键:
- 如果没有按住,解决上述情况 1;
- 如果按住了,解决上述情况 2。
然而,只监听 mousemove 事件不能笼罩所有的状况。比方,首先把鼠标挪动到指标 dom 上,此时鼠标不动,按下或者松开 ctrl 键,此时鼠标的款式是须要变动的。然而,咱们在按下或者松开 ctrl 键之后并没有挪动鼠标,所以不会触发 mousemove 事件。
所以,我就想通过 keydown 和 keyup 事件来监听 ctrl 键的按下和松开事件。
首先,我给指标 dom 增加了 keydown 事件。这时,问题就来了:keydown 事件基本就没有触发。
而后,我就想试试在 body 上绑定 keydown 事件,而后通过判断 event.target 是否是指标 dom 来判断鼠标地位。
最初,我发现 event.target 是 body 元素,而不是我想要的指标 dom。所以,我就开始查找材料,发现 keydown 事件原来和我设想中的不一样。
keydown 事件
通过查阅 MDN 上的 keydown 事件,发现该事件有如下 限度:
Keyboard events are only generated by <inputs>, <textarea> and anything with the contentEditable attribute or with tabindex=”-1″.
首先我的指标 dom 不是 input
和textarea
元素,所以就思考增加 contentEditable
或者 tabindex
属性。
首先,咱们看下 contentEditable 属性。当把这个元素设置成可编辑之后(不可编辑态不会触发 keydown 事件),元素的内容就能够像 textarea
一样进行编辑了,这个不是我要的性能,所以这种形式不行。
而后,能够设置 tabindex="-1"
。此时, 在肯定条件下 ,是能够触发 keydown 事件的。这个 肯定条件 就是,首先通过点击操作让指标 dom 处于 focus 的状态,此时再按下 ctrl 键才会触发 keydown 事件。显然,这种形式也不能满足需要。
此时,咱们先思考一个问题:为什么在第一局部给 body 增加 keydown 事件是能够的。咱们已知的信息是:
- keyboard 事件触发的条件:非凡元素,contentEditable,tabindex=”-1″。
所以,我狐疑 body 元素设置了 tabindex 属性:
document.body.tabIndex // -1
果然如此!
后面咱们有说到,只有当 dom 处于 focus 状态下的时候,按下 ctrl 键才会触发 keydown 事件。那么,对于 body 元素是不是也是这样的呢?
首先,咱们退出页面的全屏模式,而后点击不属于浏览器的中央。此时,浏览器页面处于失去焦点的状态。
咱们把鼠标从新挪动到页面的内容区域(留神,只是挪动过来,不要点击)。而后,按下 ctrl 键,你会发现 keydown 事件同样没有触发。
然而,对于 body 元素来说,先触发 focus 事件并不是一个问题。在方才页面失去焦点的状况下,把鼠标挪动到页面上有 hover 成果的元素上,发现这些元素的 hover 成果同样不会触发。所以,页面操作的默认前提应该就是页面处于 focus 状态。这样对于 body 元素来说,keydown 事件触发前首先进行 focus 操作就不是一个非凡的操作了。
解决方案
通过上述局部的内容,咱们晓得能够监听 body 元素的 keydown 事件。那么,接下来的问题就变成了怎么联合 body 的 keydown 事件来判断 ctrl 键按下或者松开的时候,鼠标是否正好在指标 dom 上。
我是通过监听 document 元素的 mousemove 事件来解决的。当 mousemove 事件触发的时候,把 event.target 保留在一个全局变量中。当 body 的 keydown 事件触发的时候,通过判断这个全局变量是否是指标 dom 来管制后续逻辑。ctrl 键松开的逻辑同理,通过 body 的 keyup 事件来监听。
总结
心愿大家能有所播种。如有谬误,欢送留言探讨。