当我们给DOM元素,既绑定click事件,又绑定dblclick事件,那么双击鼠标时,会先触发两次click之后再触发dbclick事件,那么如何实现DOM元素的click事件和dblclick事件分离呢?
下面提供一种解决方案
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>click</button>
<button>click2</button>
<script>
var btn = document.getElementsByTagName('button')[0]
function singleClick(handle, delay) {
let timer = null
return function() {
if (timer) {
clearTimeout(timer)
timer = null
return
}
timer = setTimeout(() => {
handle()
clearTimeout(timer)
timer = null
}, delay)
}
}
btn.addEventListener('click', singleClick(function() {
console.log('btn单击');
}, 250))
btn.addEventListener('dblclick', function() {
console.log('btn双击');
})
</script>
</body>
</html>
解决方案思路:
主要是帮助click事件识别单击和双击,上面signleClick函数就是帮助click事件识别单击双击的。
双击其实就是连续的两次间隔很短(200ms)的单击,所以我们只要判断两次连续单击的时间间隔是否小于200ms,如果小于200ms,则说明是双击,而不是两次单击。
按照这种思路,我们需要记录两次单击的触发时刻,然后相减,很麻烦。
我们换一种思路,第一次单击时,我们需要等待200ms,如果等待的200ms内没有发生第二次单击,则判定本次为单击,如果等待的200ms内发生了第二次单击,则判断为一次双击。
我们可以使用定时器来等待200ms,当200ms过了,就会执行定时器的回调函数(业务函数),如果200ms内,又来了一次单击,则说明是双击场景,则单击业务函数不调用,隐式关闭了单击click事件执行。