Generic Drag
See the demo page for the finished version of the code.This coding example demonstrates using a combination of mouse events to make any positioned element on a page draggable by the user.
First we'll look at how to define elements on a page so they can be dragged, then we'll see how the code works.
Setting Up Elements for Dragging
The user drags an element by placing the mouse pointer over it, pressing down on the mouse button and moving the pointer while holding the button down. Releasing the button ends the drag.
Obviously, the mousedown, mousemove
and mouseup
events will be used. And, in order for an element to be moved, it must be a
positioned element. That is, it must have a position
style of
absolute, fixed
or relative.
Since the browser gives the mouse position in pixel coordinates, the
element's left
and top
style properties should be
defined in px
units. Note that the position must be set in an
inline style (or omitted so that they will default to zero) and not in a style
rule.
To initiate a drag, an onmousedown
event handler needs to be
assigned in the element's tag to call a function named
dragStart().
Following the DOM event standard, the
event
object is passed as an argument.
<div style="position:absolute;left:200px;top:100px;" onmousedown="dragStart(event)">Drag Me</div>
Below is a DIV set up similar to the sample code above. Try dragging it around the page.
To make the script more useful, the dragStart()
function allows
an optional argument to specify the ID of a positioned element. In other words,
you can move one element by dragging the mouse on some other element, even a
non-positioned one. For example,
<div id="outerDiv" style="position:relative;left:0px;top:0px;"> <span onmousedown="dragStart(event, 'outerDiv')">Drag Me</span> <p>Some text.</p> </div>
Here, the SPAN containing the text "Drag Me" has the event handler set to drag its parent element, the DIV named "outerDiv." Below is a sample to illustrate how this works. Try dragging the DIV with the mouse over different areas.
Some text.
You'll find that you can move the DIV only if you mouse down on the text "Drag Me" and that the contents of the DIV, including the SPAN, move with it. The demo shows some more possibilities.
Also note that if you overlap the above samples, the element being dragged
always appears above the other. That's because the script updates the target
element's zIndex
style at the start of the drag.
Code Details
See the DOM Event Model for details on events and browser compatibility.The code itself is fairly simple in concept. But, as usual, certain browser incompatibilities necessitates different code for different browsers to accomplish the same task.
So first off, the script defines a global object called browser
which contains information on the particular browser and version. This is
used throughout the script to deal with any browser incompatibilities.
// Determine browser and version. function Browser() { var ua, s, i; this.isIE = false; this.isNS = false; this.version = null; ua = navigator.userAgent; s = "MSIE"; if ((i = ua.indexOf(s)) >= 0) { this.isIE = true; this.version = parseFloat(ua.substr(i + s.length)); return; } s = "Netscape6/"; if ((i = ua.indexOf(s)) >= 0) { this.isNS = true; this.version = parseFloat(ua.substr(i + s.length)); return; } // Treat any other "Gecko" browser as NS 6.1. s = "Gecko"; if ((i = ua.indexOf(s)) >= 0) { this.isNS = true; this.version = 6.1; return; } } var browser = new Browser();
The script could be extended to detect and work with other browsers as well, provided they support CSS positioning and custom event handling for the necessary mouse events.
Next the script defines a global named dragObj.
It's simply a
generic JavaScript Object
that will be used to store information
during any particular drag operation.
// Global object to hold drag information. var dragObj = new Object(); dragObj.zIndex = 0;
One initial property is set, zIndex
which will be used to set
the stacking order on that element. Here it's initialized to zero but if any
positioned elements on the page have a zIndex
set, it can be
changed to match the highest value used. This will ensure that the element
being dragged will appear on top of any others.
The rest of the script consists of the functions used to handle the three mouse events used in dragging.