我的申请一直行为不端。删除越来越多的代码后,我设法找到了问题的核心,但这对我来说毫无意义。
一点背景。我的网页编辑器应用程序对击键作出反应,例如按下Alt时,隐藏调整大小的处理程序。它还对鼠标操作做出反应,用于拖动,调整大小,删除,绘制选择框等。在尝试使用事件处理程序并防止默认行为时(我不希望Alt将焦点更改为浏览器菜单,也没有鼠标选择文本),我发现了一件奇怪的事情。
当我为keyup
和keydown
(并且这些包含preventDefault()
)创建事件处理程序时,它可以正常工作。但是,当我为mousedown
添加处理程序时,它也可以正常工作,但之前的处理程序停止工作。如果我从preventDefault()
处理程序中删除mousedown
,则一切正常。
这里我的JS代码被剥离到最低限度(或者为了验证问题而创建的代码不在其他地方):
// it works fine with these events
var events = ['keyup', 'keydown'];
// but when mousedown is added, its preventDefault() method somehow breaks keydown and keyup
//var events = ['keyup', 'keydown', 'mousedown'];
var log = document.getElementById('log');
var handler = function(e) {
log.innerHTML = e.type + '<br>' + log.innerHTML;
e.preventDefault();
}
for (var i = 0; i < events.length; i++) {
window.addEventListener(events[i], handler);
}
请参阅jsfiddle here。
为什么preventDefault()
处理程序中的mousedown
方法会干扰关键事件?
在Chrome和Firefox中测试过。
答案 0 :(得分:1)
新强>
我只需要进一步测试它。从我上次更新来看,this.focus()
似乎与documen.getElementById().focus()
和window.focus()
一样有效。最佳实践(IMO)将使用this
,因为它是对点击对象的通用引用。
最新的: New Demo
Finaly!我做错了是使用document
对象,而我应该使用window
。这次在任何测试的浏览器(甚至IE11)中控制台都没有错误。所以代码应该是这样的:
var handler = function(e) {
log.innerHTML = e.type + '<br>' + log.innerHTML;
document.focus();
e.preventDefault();
}
旧2:这次我刚刚进一步测试了这个。似乎e.preventDefault()
mousedown
上的focus
不会破坏其他事件并且正在按预期工作:防止默认操作(在其他事件中)设置DOM元素上的handler
。我在本地html文件上尝试了相同的代码,它完美无缺。你需要做的是自己设置必须阅读那些事件的对象。
编辑: DEMO以及var handler = function(e) {
log.innerHTML = e.type + '<br>' + log.innerHTML;
document.focus();
e.preventDefault();
}
功能代码:
mousedown
旧1:这是因为mouseup
事件持续到你'放手'为止(尝试相同的代码,但使用mousedown
代替keydown
)。它只是像发送事件的{{1}}一样无效,结束然后重复此事件直到你停止按键。