addEventListener 用于 Canvas 上的 keydown
Posted
技术标签:
【中文标题】addEventListener 用于 Canvas 上的 keydown【英文标题】:addEventListener for keydown on Canvas 【发布时间】:2012-10-04 21:01:06 【问题描述】:我正在尝试制作一个响应键盘和鼠标输入的画布应用程序。我有这个代码:
canvas = document.getElementById('canvas');
canvas.addEventListener('mousedown', function(event)
alert('mousedown');
, false);
canvas.addEventListener('keydown', function(event)
alert('keydown');
, false);
每当我单击鼠标时都会出现“mousedown”警报,但从未出现过“keydown”警报。相同的代码在 JS Bin 上运行良好:http://jsbin.com/uteha3/66/
为什么它不能在我的页面上运行?画布不能识别键盘输入吗?
【问题讨论】:
keydown
可能只有在画布有焦点时才会在画布上触发。我不确定画布元素是否可以拥有焦点。
【参考方案1】:
将 canvas 元素的 tabindex 设置为 1 或类似的东西
<canvas tabindex='1'></canvas>
让任何元素都具有焦点是一个古老的技巧
【讨论】:
这是我可以将按键事件侦听器分配给 html5 画布的唯一方法。我正在做 Easeljs 舞台的东西。这不起作用:$('canvas').keypress( function(e) ...
,直到我在 HTML 中添加了 tabindex。非常感谢。画架唯一的缺点,鼠标悬停事件失去焦点(例如,鼠标悬停时舞台元素的阴影)。
这对我有用,但我注意到将 tabindex 设置为 1 会阻碍 Safari 中画布的性能。【参考方案2】:
编辑 - 这个答案是一个解决方案,但更简单和正确的方法是在 canvas 元素上设置 tabindex
属性(正如 hobberwickey 所建议的那样) .
您无法聚焦画布元素。解决这个问题的一个简单方法是让你“自己”关注。
var lastDownTarget, canvas;
window.onload = function()
canvas = document.getElementById('canvas');
document.addEventListener('mousedown', function(event)
lastDownTarget = event.target;
alert('mousedown');
, false);
document.addEventListener('keydown', function(event)
if(lastDownTarget == canvas)
alert('keydown');
, false);
JSFIDDLE
【讨论】:
旧答案,但即使在 2012 年你也绝对可以:你需要给画布一个tabindex="<some number>"
和 presto:你的画布(但真的 any HTML 元素)现在可以工作了重点好。不应将此答案标记为正确,而是接受 hobberwickey 的答案。
我同意你的观点,但无论出于何种原因,@Cbas 从未接受 hobberwickeys 的回答。我已经更新了我的帖子以供未来的访问者解决这个问题。【参考方案3】:
将所有 js 代码封装在一个 window.onload 函数中。我有一个类似的问题。一切都在 javascript 中异步加载,因此某些部分的加载速度比其他部分更快,包括您的浏览器。将所有代码放入 onload 函数将确保您的代码在尝试执行之前从浏览器中需要的所有内容都可以使用。
【讨论】:
【参考方案4】:有时只需将画布的 tabindex 设置为“1”(或“0”)即可。但有时 - 它不会,出于某种奇怪的原因。
就我而言(ReactJS 应用程序、动态画布 el 创建和挂载),我需要调用 canvasEl.focus() 来修复它。 也许这与 React 有某种关系(我基于 KnockoutJS 的旧应用程序在没有 '..focus()' 的情况下工作)
【讨论】:
以上是关于addEventListener 用于 Canvas 上的 keydown的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript addEventListener 不适用于 onDrop、onDragOver 或 onDragStart
js addeventlistener 为 dragenter 使用捕获不适用于输入元素