起因:
最近在做一個可拖拽的拓撲圖,遇到的這個問題:如果執行拖拽操作的時候鼠標拖動很快,可能會出現鼠標脫離頁面乃至瀏覽器的范圍,如果這時松開鼠標按鍵,那么將不能響應鼠標的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了。
百度地圖和谷歌地圖都實現了瀏覽器外響應拖拽事件的效果,不知道他們是否是通過上述方法實現的。還請大神留言相告,謝謝。