2009-11-06 74 views
25

在Internet Explorer 7 體的OnMouseMovedocument.onmousemove事件似乎只是對火當鼠標在瀏覽器窗口中,而不是在它的外面。然而在Firefox中,當我移出瀏覽器窗口時,onmousemove事件被正確調用。爲了響應的OnMouseMove事件瀏覽器窗口外,在IE

如何設置在IE瀏覽器窗口之外調用的事件?

Google Maps在IE中這樣做。如果按住鼠標按鈕並將鼠標移動到瀏覽器窗口外部,則可以看到地圖仍然移動。

回答

62

(注意:此答案專門針對mousedown -> mousemove -> mouseup的「標準」拖動實施,它不適用於HTML5 drag specification)。

允許在瀏覽器窗口外面拖動是一個老問題,不同的瀏覽器可以通過兩種方式解決。

除IE外,當用戶通過mousedown啓動拖動操作時,瀏覽器已經做了一些簡單的事情(這完全是出於觀察):一種狀態機開始處理鼠標移動的特殊情況窗口:

  1. 用戶觸發document
  2. 用戶內部mousedown事件觸發事件mousemove。事件觸發從document(即窗口)的外部觸發即使
  3. 用戶觸發(內部或外部documentmouseup事件。 mousemove事件從文檔不再火

IE和舊版本的Firefox [遲至2.0.20]不出現此行爲外觸發。窗外拖動不起作用。

IE和FF2的問題實際上在於元素是否「可選」或不是(請參閱herehere)。如果拖動實現不執行任何操作(從而允許通過鼠標進行選擇),則所述實現不必考慮窗外的移動;瀏覽器將繼續並正確啓動mousemove,並允許用戶在窗外自由拖動。尼斯。

但是,通過讓瀏覽器決定在mousemove上做什麼,你會得到這種效果,瀏覽器認爲用戶試圖「選擇」某些東西(例如元素),而不是移動它,然後瘋狂地嘗試當鼠標在拖動過程中穿過或離開元素時,突出顯示其中的元素或文本。

大多數拖動實現我見過做一個小動作,使元素被拖動「不可選擇」,從而採取的mousemove完全控制模擬拖:

elementToDrag.unselectable = "on"; 
elementToDrag.onselectstart = function(){return false}; 
elementToDrag.style.userSelect = "none"; // w3c standard 
elementToDrag.style.MozUserSelect = "none"; // Firefox 

這工作得很好,但拖着斷在窗外

反正,回答你的問題,讓IE(所有版本),讓窗外的拖動,使用setCapture(成反比releaseCapture鼠標被釋放時)。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>Simple drag demo</title> 
<style> 
#dragme { 
    position:absolute; 
    cursor:move; 
    background:#eee; 
    border:1px solid #333; 
    padding:10px; 
} 
</style> 

<script> 
function makeDraggable(element) { 

    /* Simple drag implementation */ 
    element.onmousedown = function(event) { 

    document.onmousemove = function(event) { 
     event = event || window.event; 
     element.style.left = event.clientX + 'px'; 
     element.style.top = event.clientY + 'px'; 
    }; 

    document.onmouseup = function() { 
     document.onmousemove = null; 

     if(element.releaseCapture) { element.releaseCapture(); } 
    }; 

    if(element.setCapture) { element.setCapture(); } 
    }; 

    /* These 3 lines are helpful for the browser to not accidentally 
    * think the user is trying to "text select" the draggable object 
    * when drag initiation happens on text nodes. 
    * Unfortunately they also break draggability outside the window. 
    */ 
    element.unselectable = "on"; 
    element.onselectstart = function(){return false}; 
    element.style.userSelect = element.style.MozUserSelect = "none"; 
} 
</script> 
</head> 
<body onload="makeDraggable(document.getElementById('dragme'))"> 

<div id="dragme">Drag me (outside window)</div> 

</body> 
</html> 

Demo can be seen here

這正是谷歌地圖所做的事情(正如我在2004年穀歌地圖反向工程首次發佈時發現的那樣)。


我認爲它實際上只啓動一個textnode拖動操作(即mousedown)下破壞。元件/容器節點不表現出相同的行爲,並且可以內部或文檔外周圍拖動,設置在用戶將鼠標向下在元件的一個「空」部分

再次,對於拖灌頂上textnodes。

+0

輝煌答案! – 2009-11-17 00:49:04

+0

這讓我非常沮喪! IE需要Capture並擁有它。其他人正確地檢測文檔外的mouseup。 – 2012-06-20 04:10:24

+0

Hi Crecent Fresh,我有一種情況,每當有一個'mousedown'後面有'mouseup'時,就會彈出一個警告。所以,在文檔上打開「mousedown」後,如果用戶將鼠標從窗口拖出,並將鼠標放在窗口外面,則會彈出警報。我該怎麼做?我沒有太多的理解你的代碼,因爲它涉及到選擇和拖動等東西。 – SexyBeast 2013-02-13 11:38:57

2

你可以看看這裏的代碼,因爲它似乎在IE8和FF3.5中工作。如果你能理解他的代碼很棒。 http://www.walterzorn.de/en/dragdrop/dragdrop_e.htm

+1

謝謝。這是非常蹩腳的代碼,但他似乎也在使用document.onmousemove,我不知道這個祕密是什麼? – 2009-11-06 04:27:06

+0

我不知道,我沒有太多檢查代碼,但是您可能想要在Firefox上使用Firebug,或者在IE上使用W​​eb Developer工具包,以查看將鼠標移到瀏覽器外部時發生了什麼。 – 2009-11-06 04:47:23

+0

謝謝。當我移動鼠標時,如何查看Firebug中發生的事情或IE上的Web Developer工具包?我已經看過所有這些,但沒有看到任何方式來觀看事件。 – 2009-11-06 07:57:29