JavaScript excels at modifying the DOM of a Web page, but we usually only do simple things with it, such as creating image rollovers, making tabs, etc. This article is going to show you how to create items on your page that you can drag and drop.
There are several reasons you might want to encorporate this drag and drop ability into your Web pages. One of the simplest reasons is to reorganize Data. As an example, you might want to have a queue of items that your users can reorganize. Instead of putting an input or select box next to each item to represent its order, you could make the entire group of items draggable. Or perhaps you want to have a navigation window on your site that can be moved around by your users. Then there's always the simplest reason: because you can!
There's really not much involved with dragging an item around on your Web page. First we have to know where the mouse cursor is, second we need to know when the user clicks on an item so that we know we should be dragging it, and finally we need to move the item.
Demo - Drag any of the images
Capturing Mouse Movement
document.onmousemove
:
We must first explain the event object. Whenever you move the
mouse, click, press a key, etc., an event is fired. in Internet Explorer this
event is global; it's stored in window.event. In Firefox, and other browsers,
this event is passed to whatever function is attached to the action. Since we
attached the mouseMove function to document.onmousemove
, mouseMove
gets passed
the event object.
To make ev
contain the event object in every browser we OR
it with
window.event
. In Firefox the " || window.event
" will be ignored since ev
already
contains the event. In IE ev
is null so it will get set to window.event
.
Since we'll need to obtain the mouse coordinates many times over this article
we make a mouseCoords
function that takes one argument: the event.
Again we run into differences between IE and other browsers. Firefox and
other browsers use event.pageX
and event.pageY
to represent the mouse position
relative to the document. If you have a 500x500 window and your mouse is in the
middle, pageX
and pageY
will both be 250. If you then scroll down 500 pixels
pageY will now by 750.
Contrary to this, IE decided to use event.clientX
and event.clientY
to
represent the mouse position relative to the window, not the document. In our
same example clientX
and clientY
will both be 250 if you put your mouse at the
middle of a 500x500 window. If you scroll down on the page, clientY
will remain
250 since it is measured relative to the window and not where you are on the
document. As a result we need to add the scrollLeft
and scrollTop
properties
of the document body to our mouse position. Finally, the document in IE isn't
actually at the 0,0 position. There is a small (usually 2px) border surrounding it.
document.body.clientLeft
and clientTop
countain the width of this border, so we
add those also to our mouse position.
Fortunately since we now have our mouseCoords
function we don't have to worry about this again.
Capturing Mouse Clicks
Next we need to know when your mouse button is pressed and when it is released. If we skip this step you would be "dragging" items whenever your mouse happened to move over them. This would be both annoying and counterintuitive.
There are two more functions that help us here: onmousedown
and onmouseup
. We
previously attached a function to document.onmousemove
, so it only seems logical
that we would attach functions to document.onmousedown
and document.onmouseup
.
If we attach a function to document.onmousedown
, however, our function would get
fired on any object we click on: text, images, tables, etc. We only want certain
items on our page to be draggable so we instead attach a function to the
onmousedown
event of whatever we want to move.
We now have a variable, dragObject
, that contains any item you click on.
If you release the mouse button dragObject
gets set to null. So if dragObject != null
we know that we should be dragging something.
Moving an Item
We now know how to capture
mouse movements and clicks. All that's left to do is move around whatever we
want to drag. First, to move an item to exactly where we want it to be on a
page, the style position of that item must be set to 'absolute'. Setting an
item's position to absolute means that when you set a style.top
or style.left
on
the item, the measurements are relative to the top-left of your page. Since all
of our mouse movements are also relative to the top-left of our page, this is
generally the way to go.
Once we set item.style.position='absolute'
, all we have to do is change the
top or left position of the item and voila, it's moved!