在IE浏览器窗口外响应onmousemove事件

IT技术 javascript internet-explorer javascript-events
2021-02-22 01:30:04

在 Internet Explorer 7正文中,onmousemovedocument.onmousemove事件似乎仅在鼠标位于浏览器窗口内时触发,而不是在鼠标位于外部时触发。然而,在 Firefox 中,当我移动到浏览器窗口之外时,会正确调用 onmousemove 事件。

如何设置要在 IE 浏览器窗口外调用的事件?

谷歌地图在 IE 中做到了这一点。如果您按住鼠标按钮并将鼠标移到浏览器窗口之外,您可以看到地图仍在移动。

2个回答

(注意:此答案仅指 的“标准”拖动实现mousedown -> mousemove -> mouseup。它不适用于HTML5 拖动规范)。

允许拖动到浏览器窗口外是一个老问题,不同的浏览器已经通过两种方式解决了。

除了 IE 之外,当用户通过mousedown浏览器启动拖动操作时,已经做了一些巧妙的事情(这只是观察):一种状态机开始处理鼠标在窗口外移动的特殊情况:

  1. 用户mousedown在内部触发事件document
  2. 用户触发mousemove事件。即使从外部(即窗口)触发事件也会触发document
  3. 用户触发mouseup事件(内部或外部document)。mousemove从文档外部触发的事件不再触发

IE 和旧版本的 Firefox [迟至 2.0.20] 不会出现这种行为。在窗口外拖动是行不通的1

IE 和 FF2 的问题实际上在于元素是否“可选”(参见此处此处)。如果拖动实现什么都不做(从而允许鼠标选择),则所述实现不必考虑窗口外的移动;浏览器将继续并mousemove正确触发,并且允许用户在窗口外自由拖动。好的。

然而,通过让浏览器决定在 mousemove 上做什么,你会得到这种效果,浏览器认为用户正在尝试“选择”某些东西(例如元素),而不是移动它,并继续疯狂地尝试突出显示元素或当鼠标在拖动过程中移入或移出元素时,其中的文本。

我见过的大多数拖动实现都做了一个小技巧,使被拖动的元素“不可选择”,从而完全控制mousemove模拟拖动:

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

这很好用,但在窗口外拖动会中断2

无论如何,要回答您的问题,让 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>

演示可以在这里看到

这正是谷歌地图所做的(正如我在 2004 年首次发布谷歌地图时对谷歌地图进行逆向工程后所发现的那样)。


1我相信它实际上只有mousedown在文本节点上启动拖动操作(即时才会中断元素/容器节点不表现出相同的行为,可以在文档内部或外部拖动,前提是用户将鼠标放在元素的“空”部分

2再次,用于文本节点上的拖动启动。

这让我少了很多挫折!IE 是需要 Capture 并拥有它的那个。其他人正确地检测到文档外的mouseup。
2021-04-28 01:30:04
嗨,Crescent Fresh,我有一个案例,只要有mouseup一个mousedown,就会弹出一个警报。因此,在mousedown文档上,如果用户在鼠标仍然按下的情况下将鼠标拖出窗口,然后将其释放到窗口外,则应弹出警报。我该怎么做?我不太了解你的代码,因为它涉及选择和拖动之类的东西......
2021-05-16 01:30:04

你可以在这里查看代码,因为它似乎在 IE8 和 FF3.5 中工作。如果你能理解他的代码就好了。 http://www.walterzorn.de/en/dragdrop/dragdrop_e.htm

我不知道,我没有过多地检查代码,但是您可能想使用 Firefox 上的 Firebug 或 IE 上的 Web Developer 工具包来观察将鼠标移出浏览器时发生的情况。
2021-04-19 01:30:04
你可以试试这个,并在控制台中观看: console.info("y is Greater than x")
2021-05-04 01:30:04
谢谢。代码很烂,但他似乎也在使用 document.onmousemove,我想知道其中的秘密是什么?
2021-05-06 01:30:04
谢谢。当我移动鼠标时,我将如何观察 Firebug 或 IE 上的 Web Developer 工具包中发生的事情?我已经查看了所有这些,但没有看到任何观看事件的方法。
2021-05-10 01:30:04
我还注意到,在 walterzorn.com/dragdrop/dragdrop_e.htm 中,只有图像可以用鼠标移出窗口,而不是底部的 div 示例。与 Google 地图类似,您实际上是在四处拖动图像,而不是 HTML 元素。也许是 IE 的一个限制,只有图像拖动事件或其他东西可以在页面外工作?
2021-05-15 01:30:04