事件繫結中,執行雙擊事件(dblclick)時能觸發兩次單擊事件(click)。即一個標籤元素(如button等),如果元素同時繫結了單擊事件(click)和雙擊事件(dblclick),那麼執行單擊事件(click)時,不會觸發雙擊事件(dblclick), 執行雙擊事件(dblclick)時卻會觸發兩次單擊事件(click)。
先看一下點選事件的執行順序:
單擊(click):mousedown,mouseout,click;
雙擊(dblclick):mousedown,mouseout,click , mousedown,mouseout,click,dblclick;
在單擊的時候不會執行雙擊,但是雙擊的時候會執行兩次單擊再執行雙擊事件。
解決的思路:使用定時器清除掉兩個單擊事件,留下一個雙擊事件。
setTimeout
<button onclick="single(event)" ondblclick="double(event)">按鈕</button>
var time = 200;
var timeOut = null;
function single (e) {
clearTimeout(timeOut); // 清除第一個單擊事件
timeOut= setTimeout(function () {
console.log(`單擊`);
// 單擊事件的程式碼執行區域
// ...
}, time)
}
function double (e) {
clearTimeout(timeOut); // 清除第二個單擊事件
console.log(`雙擊`)
// 雙擊的程式碼執行區域
// ...
}
然後現在,單擊按鈕列印“單擊”,雙擊按鈕列印“雙擊”。
關於 time=200,大家知道js的事件迴圈機制,點選事件會新增一個任務佇列。time=0, 也會新增一個任務佇列。那麼time=0與time=200有什麼區別呢?
因為第一次單擊事件後,主執行緒沒有任何任務,就會立馬執行這個單擊事件的任務。待第二次單擊的時候,假設距離第一次單擊事件是150ms, 如果你的定時器小於150ms, 那麼第一次的任務佇列就會執行完。
要想不執行第一次的任務佇列,那麼定時器時間間隔就必須大於兩次單擊的時間間隔了。所以,這個200是酌情值,大於間隔就行。
第一次單擊任務不執行了,是被定時器延時,然後第二次點選的時候給清除了。那麼第二次點選事件呢?
在兩次單擊之後,會立馬執行一個雙擊事件,雙擊事件的一開頭就把這個第二次點選事件給清除了。
這就是雙擊事件的大概過程。