[ACCEPTED]-Responding to the onmousemove event outside of the browser window in IE-javascript-events

Accepted answer
Score: 71

(Note: this answer refers exclusively to 40 the "standard" drag implementation 39 of mousedown -> mousemove -> mouseup. It is not applicable to the HTML5 drag specification).

Allowing 38 dragging outside the browser window is an 37 old problem that different browsers have 36 solved in two ways.

With the exception of 35 IE, when a user initiates a drag operation 34 via mousedown browsers have done something neat (and 33 this is all just from observation): a kind 32 of statemachine kicks in to handle the special 31 case of mouse movements outside the window:

  1. User triggers mousedown event inside the document
  2. User triggers mousemove event. Event fires even when triggered from outside the document (i.e. the window)
  3. User triggers mouseup event (inside or outside the document). mousemove events triggered from outside the document no longer fire

IE 30 and older versions of Firefox [as late as 29 2.0.20] don't exhibit this behavior. Dragging 28 outside the window just doesn't work1.

The 27 problem for IE and FF2 actually lies in 26 whether an element is "selectable" or 25 not (See here and here). If a dragging implementation 24 does nothing (thereby allowing selection 23 by the mouse), then said implementation 22 does not have to account for movements outside 21 the window; the browser will go ahead and 20 fire mousemove properly and the user is allowed to 19 drag freely outside the window. Nice.

However 18 by letting the browser decide what to do 17 on mousemove you get this effect where the 16 browser thinks the user is trying to "select" something 15 (eg the element), as opposed to moving it, and 14 proceeds to frantically try to highlight 13 the element or text therein as the mouse 12 crosses in or out of the element during 11 the drag.

Most drag implementations I've 10 seen do a little trick to make the element 9 being dragged "unselectable", thereby 8 taking full control of mousemove to simulate dragging:

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

This 7 works nicely, but breaks dragging outside the window. 2

Anyway, to answer your question, to 6 get IE (all versions) to allow dragging 5 outside the window, use setCapture (and inversely 4 releaseCapture when the mouse is released).

<!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.

This is exactly 3 what Google maps does (as I discovered since 2 reverse engineering google maps back in 1 2004 when it was first released).


1I believe it actually only breaks when initiating a drag operation (i.e. mousedown) on a textnode. Element/container nodes do not exhibit the same behavior and can be dragged around inside or outside the document, provided the user moused down on an "empty " portion of the element

2Again, for drag initiations on textnodes.

Score: 2

You can look at the code here, as it seems 2 to work in IE8 and FF3.5. If you can understand 1 his code great. http://www.walterzorn.de/en/dragdrop/dragdrop_e.htm

More Related questions