js拖拽——將鼠標事件響應范圍擴大到整個系統桌面


起因:

最近在做一個可拖拽的拓撲圖,遇到的這個問題:如果執行拖拽操作的時候鼠標拖動很快,可能會出現鼠標脫離頁面乃至瀏覽器的范圍,如果這時松開鼠標按鍵,那么將不能響應鼠標的onmouseup事件,從而導致onmouseup和onmousemove事件不能被釋放掉。

對於這個問題,網上很多相似的文章寫了解決辦法,但都有些毛病,我在這里總結歸納一下。

解決辦法:

方案一:針對ie和火狐瀏覽器

ie瀏覽器和Firefox提供了setCapture 和 releaseCapture函數來解決該問題。簡單寫個小例子:

 1 /*...html部分略...*/
 2 
 3 var i = 0;
 4 div1.onmousedown = function() {
 5       div1.setCapture(); //用dom元素調用該函數相當於將該dom元素上的事件交給操作系統去維護,從而讓該dom元素上的事件響應不依賴於瀏覽器
 6       div1.onmousemove = function() {
 7          console.log(i++);
 8       }
 9       div1.onmouseup = function() {
10           div1.onmouseup = null;
11         div1.onmousemove = null;
12         div1.releaseCapture(); //拖拽結束后要釋放掉
13       }
14 }

 

方案二:針對chrome瀏覽器

悲催的是chrome瀏覽器並沒有提供上述函數的實現,那只能另辟蹊徑了。方法就是在window對象上注冊onmousedown、onmousemove、onmouseup事件。這樣只要在窗口內觸發onmousedown事件之后,無論您鼠標移動到什么地方,都能onmousemove和onmouseup事件。至於您要對哪個具體的dom元素進行操作,您可以在onmousedown事件的回調函數中通過event.target獲取目標元素對象,然后再用call去執行相應函數即可。例子如下:

 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <title></title>
 6 </head>
 7 
 8 <body>
 9 <div id="div1" style="width:100px; height:100px; border:1px solid red">
10     
11 </div>
12 
13 </body>
14 </html>
15 <script>
16     var i = 0;
17     window.onmousedown= function(event) {
18         var targetObj = event.target;
19         if (targetObj.id == "div1") { //只有在id為div1的元素上按下鼠標左鍵才能觸發鼠標移動事件
20             window.onmousemove = function() {
21                 div1Move.call(targetObj);
22             }
23             window.onmouseup= function() {
24                 window.onmouseup = null;
25                 window.onmousemove = null;
26             }
27         }
28     }
29     
30     //鼠標移動時執行的事件
31     function div1Move() {
32         console.log(i++);
33     }
34 </script>

注意:1、該解決方案不適用於ie8及以下瀏覽器。因為這些瀏覽器不支持在window對象上注冊事件。 2、該解決方案也不適用於iframe,您可以把上面的例子放到iframe中去試一試。原因大概是因為系統只維護最頂層window上的事件。

 

總結:結合方案一和方案二可以解決瀏覽器的兼容性問題,但是由於方案二對於iframe無效,所以在實現有拖拽需求的頁面時,只能不用iframe了。

百度地圖和谷歌地圖都實現了瀏覽器外響應拖拽事件的效果,不知道他們是否是通過上述方法實現的。還請大神留言相告,謝謝。


免責聲明!

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



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