在前端開發工作中,會遇到這樣問題:針對同一個dom元素,即希望為它綁定click事件,又想該元素可以允許拖拽的效果。而使用拖拽的效果,我們一般就會用到mousedown,mousemove和mouseup事件。但mousedown、mouseup就會和click事件發生衝突。我們希望在拖拽元素的時候 ...
在前端開發工作中,會遇到這樣問題:針對同一個dom元素,即希望為它綁定click事件,又想該元素可以允許拖拽的效果。而使用拖拽的效果,我們一般就會用到mousedown,mousemove和mouseup事件。但mousedown、mouseup就會和click事件發生衝突。我們希望在拖拽元素的時候不希望它執行click方法,在執行click方法是不希望執行mousedown和mouseup方法。
比如如下代碼,就會出現上面的問題:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="js/jquery-1.11.2.js"></script> <script> $(function(){ $("#mydiv").on("click",function(){ console.log("this is click event"); }); $("#mydiv").on("mousedown",function(){ console.log("this is mousedown event"); }); $("#mydiv").on("mouseup",function(){ console.log("this is mouseup event"); });
}); </script> </head> <body> <div id="mydiv" style="width:200px;height:200px;background: red;"> </div> </body> </html>
上述代碼在控制台的輸出結果如下:
this is mousedown event
this is mouseup event
this is click event
可以看到,mousedown 和mouseup是優先於click事件先執行的。
而我們希望的效果是,在移動元素的操作中不執行click事件,在執行click事件時不調用mousedown和mouseup方法。
區分click事件和滑鼠拖拽元素後在鬆開事件其實很簡單,用一個全局標識符就可以了。
我們不用在為元素綁定click事件,而是只使用它的mousedown,mousemove,mouseup事件來判斷是否該元素被拖拽了。
具體參見代碼,可以看註釋:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="js/jquery-1.11.2.js"></script> <script> $(function(){ var hasMove=false; //全局標識,初始化標識元素沒有發生mousemove $("#mydiv").on("mousedown",function(){ hasMove=false; }); $("#mydiv").on("mouseup",function(){ //根據是否發生移動狀態來模擬click事件和拖拽後釋放滑鼠事件 if(hasMove){ console.log("移動後滑鼠鬆開事件"); }else{ console.log("沒有移動滑鼠鬆開事件,模擬click"); } hasMove=false; //還原標識,以便下一次使用 }); $("#mydiv").on("mousemove",function(){ hasMove=true; //元素移動事件中跟新標識為true,表示有發生移動 }); }); </script> </head> <body> <div id="mydiv" style="width:200px;height:200px;background: red;"> </div> </body> </html>
效果和控制台如圖
如此,放棄使用click事件機制,以mousemove事件和mouseup事件動態改變全局標識符,來區分在滑鼠釋放一刻元素是否發生移動,以此來判斷該事件是click還是拖拽。
感謝閱讀。