(注:此答案仅指
mousedown -> mousemove -> mouseup
. 不适用于
HTML5 drag specification
)。
允许在浏览器窗口外拖动是一个古老的问题,不同的浏览器通过两种方式解决了这个问题。
除了IE,当用户通过
mousedown
浏览器做了一些简单的事情(这都是从观察中得到的):一种状态机开始处理窗口外鼠标移动的特殊情况:
-
用户触发器
鼠标按下
事件内部
document
-
用户触发器
mousemove
事件。事件火灾
即使从外部触发
文件
(即窗户)
-
用户触发器
mouseup
事件(内部或外部
文件
)
移动鼠标
从文档外部触发的事件
不再火
IE和旧版本的Firefox[最迟2.0.20]没有表现出这种行为。在窗口外拖动不起作用
一
.
IE和FF2的问题实际上在于元素是否“可选”(参见
here
和
here
)如果拖动实现什么都不做(从而允许鼠标选择),则所述实现不必考虑窗口外的移动;浏览器将继续并启动
移动鼠标
用户可以在窗口外自由拖动。很好。
但是,通过让浏览器决定对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上。元素/容器节点不表现出相同的行为,并且可以在文档内部或外部拖动,前提是用户将鼠标向下移动到元素的“空”部分。
二
同样,对于文本节点上的拖动启动。