2009-11-06 75 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