2002-05-24: First public version released

Introduction

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.

DOM Modules

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

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.

DOM Level 2 Events

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.

DOM Level 2 Views

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.

DOM Level 2 Style

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" )

Implementation

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.

Testing DOM Support

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.

Usage

Next we take a look how to use this script as well as show you some demo elements.

DOM Generic Move
Usage and Demo
Download

Author: Erik Arvidsson