本文解析JavaScript中键盘事件与鼠标事件的触发机制。键盘按下时依次触发keydown、keypress和keyup;长按时重复触发前两者。针对click与dblclick共存时的冲突,通过setTimeout延迟执行click逻辑,并在触发dblclick时清除定时器,确保双击时不执行单击处理。
键盘事件触发顺序与长按行为
首先提供一段用于测试键盘事件的代码示例:
<script type="text/javascript">
document.onkeydown = function(){
document.getElementById("test").innerHTML += "keydown<br/>";
}
document.onkeyup = function(){
document.getElementById("test").innerHTML += "keyup<br/>";
}
document.onkeypress = function(){
document.getElementById("test").innerHTML += "keypress<br/>";
}
</script>
<div id="test"></div>
根据测试输出结果:
keydown
keypress
keyup
可以明确得出,键盘事件的触发顺序依次为:keydown、keypress、keyup。
若按住按键一段时间后再松开,测试结果如下:
keydown
keypress
keydown
keypress
keydown
keypress
keydown
keypress
...
keyup
此时会触发n次keydown和n次keypress,仅触发1次keyup,重复频率由系统设定的时间间隔决定。
解决click与dblclick事件冲突的方法
关于click和dblclick事件的讨论
此前有开发者询问如何处理click和dblclick共存的情况:要求两者有不同的处理函数,但当触发dblclick时,不应执行click的处理逻辑。以下是解决方案的整理。
先观察事件触发情况,测试代码如下:
<script type="text/javascript">
document.onclick = function(){
document.getElementById("test").innerHTML += "click<br/>";
}
document.ondblclick = function(){
document.getElementById("test").innerHTML += "dblclick<br/>";
}
</script>
<div id="test"></div>
双击时的输出结果如下:
click
dblclick
若放慢点击速度,结果如下:
click
click
click
由此可见,触发dblclick时,系统会先触发一次click事件;若在系统设定的双击延迟时间内再次发生click事件,则判定为dblclick。
针对上述需求,解决方案代码如下:
<script type="text/javascript">
function clickTest(){
document.getElementById("test").innerHTML += "click<br/>";
}
function dblclickTest(){
document.getElementById("test").innerHTML += "dblclick<br/>";
}
document.onclick = function(){
this.timeout = window.setTimeout(clickTest,300);
}
document.ondblclick = function(){
if(this.timeout)window.clearTimeout(this.timeout);
dblclickTest();
}
</script>
<div id="test"></div>
双击测试的最终结果如下:
dblclick
dblclick
dblclick
dblclick