2002-05-24: First public version released
Back in 1997 (when WebFX was run by Emil alone and I had my personal DHTML page) I created the first version of the Generic Move script for Internet Explorer 4.0. This was later updated to fix issues with IE5. At the time of the original script the thought of making this script work in other browsers than IE never really occured to me. At that time there was only one browser that allowed things like these to be done. Sure Netscape Navigator 4.0 could be used for similar things but allowing any element on the page to be movable was just not possible.
Now, almost 5 years later, the scene has changed. The standards developed by the W3C are gaining acceptance all over and some excellent browsers are finally getting ready for prime time. The remake of the generic move script is implemented in better structured code and it only uses W3C DOM standards. Yes, that means no more proprietary extensions and no more browser tests.
The DOM Generic Move script requires support for DOM level 1 and DOM level 2. Below is a short description of the different parts of DOM that are used and what they are used for.
DOM level 1 is used to find an element in the page using
document.getElementById and it is also used to read attribute
values. The property className, from the HTML part, is used
to find draggable elements.
To listen to mouse events the method addEventListener is used.
This method allows you to listen to events without overwriting any previous
listeners. In this way conflicts can be minimized.
To find the element that the user wants to move the target
property of the event object is used. To allow the user to start the drag by
clicking on a child node of the draggable element the real element is found by
walking up the parentNode chain.
Once a valid movable element is found we also need to prevent the default
actions of the browser to occur. This is done by calling
preventDefault on the event object. To allow nested elements to be
moved we also stop the event propagation, using stopPropagation so
that only one element is moved at the same time.
To calcualte the new position we need to find where the mouse pointer is
currently located. This is done using screenX and
screenY. The distance to move is the difference between the current
mouse position and the position where the mouse was pressed.
This module is used in conjunction with the style module. This allows us to find the abstract view of the document so we can find the computed style values. See below.
The CSS part of this is used to update the position of an element by setting the
style.left and style.top for an element. It is also
used with the defaultView to get the computed style for the left
and top style properties.
document.defaultView.getComputedStyle(el, null).getPropertyValue( "left" )
The idea behind this script is to listen to the mousedown
event on the document. Once the user presses down the mouse on an
element the mousedown event is fired. This event bubbles up to the
document where we catch it. Here we check the className of the
target node and all its parent nodes. If we find a node that fits
our class name test we start a drag.
The move is done by updating the left and top position. The distance to move is the distance the mouse has moved from the point where it was pressed down.
Unfortunately not all browsers support the needed parts of the W3C DOM
standards and therefore we need to test this. To test a certain feature of the
DOM we use the document.implementation.hasFeature method. Notice
that some browsers do not even have the object
document.implementation defined so we need to test that first.
if ( typeof document.implementation != "undefined" &&
document.implementation.hasFeature("HTML", "1.0") &&
document.implementation.hasFeature("Events", "2.0") &&
document.implementation.hasFeature("CSS", "2.0") ) {
...
}
Notice that we do not need to test support for Views because
if the CSS module is supported so is the Views
module.
Next we take a look how to use this script as well as show you some demo elements.