mouseup模擬drag與click事件沖突


今天要說一個很隱晦的東西,一般可能很難碰到,碰到了可能很難解決。就是當我們自己用mousestart,mousemove,mouseup做自定義拖拽效果的時候,如果這個時候配上click就會引發一個拖拽穿透的bug。

mouseup模擬drag與click事件沖突(二維碼)    

點擊上面的鏈接,用鼠標拖住上下拖拽可滾動列表,然后你會發現,如果你的鼠標在某一個具體的列表項上,就會觸發查看詳情,其實查看詳情是click之后才會觸發的,但是這里很明顯自定義拖拽觸發了click。(注:此bug pc上才有,手機端沒有)

問題分析

其實這種問題一般情況下是很難遇到的,只會有某些框架里面出現這種bug,那我們看看這種問題到底是如何出現的。

首先自定義拖拽是利用mousestart,mousemove,mouseup三個事件組合形成的,但是mouseup執行之后,click是一定會執行的,是無法避免的,是無法用preventDefault,stopPropagation,stopImmediatePropagation阻止的。本例的demo中就在mouseup之后執行了上述阻止事件傳播的方法,但是並沒有效果。因為mouse事件和click事件本身就不是一個系列的,因此沒有關系,所以當發生拖拽之后,mouseup一定會執行,click也會在mouseup執行后執行。

解決方案

首先我們可以解決最簡單的一種,就是不拖拽的情況下觸發只是觸發click。

按照剛才的說法,mouseup事件后click必定會觸發,但是如果沒有發生拖拽,也就是沒有觸發mousemove事件,這種情況比較簡單,我們可以用一個變量紀錄是否觸發mousemove,在mouseup的時候只觸發發生拖拽的情況。

還有一種比較復雜的情況,就是在發生了拖拽的情況下如何避免click的觸發?這個時候我們用一個定時去控制一個全局變量,讓這個變量在200毫秒之后發生改變,因此mouseup之后click很快就觸發了,不到200ms,因此可以保證變量還沒有發生變化,click事件里面去檢測這個變量,如果是變化之前,那么不執行。具體代碼如下:

1 //mouseup事件里定時改變一個變量
2 window.mouseup_click_debug = true;
3 setTimeout(function() {
4     window.mouseup_click_debug = false;
5 }, 200);
6 //click事件里去檢測這個變量是否發生改變,如果沒改變,說明mouseup剛執行完,這里不執行
7 if(window.mouseup_click_debug) {
8     return false;
9 }

解決后的demo如下:

解決后demo:mouseup模擬drag與click事件沖突(二維碼)

轉自:http://www.qiutianaimeili.com/html/page/2018/09/5c9jxp7u6ng.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM