Drag & Drop in Navigator 4: Drag-Enabling Many Elements | WebReference

Drag & Drop in Navigator 4: Drag-Enabling Many Elements


Drag & Drop in Navigator 4:
drag-enabling many elements

There will be many cases where more than one element should be draggable. Instead of assigning event handlers to each such element, we will capture the required events for the whole document and then isolate the element the event was meant for.

First, initialize a global variable to track the element being dragged, if any. This variable, whichEl, will contain a null value if no element is being dragged, and the element itself if a drag is in progress.

    whichEl = null;

At the end of the script, capture and assign the mousedown and mouseup events:

    document.captureEvents(Event.MOUSEDOWN | Event.MOUSEUP); document.onmousedown = grabEl; document.onmouseup = dropEl;

But let's backtrack for a moment. First we must choose which elements will be draggable on our page. We can expand our example to four squares. There are many ways of listing the draggable elements. One way is listing them in an array. This method has the advantage of existing outside of the HTML. Another method, and more condusive to the cross-browser version we will be developing, is to mark the draggable elements by including a unique identifier in their ID. For example, the word "DRAG" appearing anywhere in the ID, allows three of these four elements to be dragged. Don't forget that they must be properly defined in <STYLE> or with the STYLE= attribute.

    <DIV ID="elDRAGOne"></DIV> <DIV ID="elTwoDRAG"></DIV> <DIV ID="DRAGelThree"></DIV> <DIV ID="elFour"></DIV>

Our grabEl has to now be completely changed to accomodate more than one possible element. First off, we assign the page location of the mousedown to two variables for easier reference:

    function grabEl(e) { mouseX = e.pageX; mouseY = e.pageY; }

We now create a for loop that will cycle through the document's layer array. All CSS-positioned elements are part of the layers array. First it checks to see if "DRAG" is part of the element's ID. If it isn't, it encounters the continue statement which loops execution back the increment expression. Whenever an element is encountered that is DRAGable, the loop checks if the mouse click occured within the element's page boundaries. An element's left boundary is, of course, its left property. Its right boundary is its clip width plus its left boundary, since we are concerned with the visible (clipped) part of the element, only.

    function grabEl(e) { mouseX = e.pageX; mouseY = e.pageY;
for ( i=0; i<document.layers.length; i++ ) { tempLayer = document.layers[i]; if ( tempLayer.id.indexOf("DRAG") == -1 ) { continue } if ( (mouseX > tempLayer.left) && (mouseX < (tempLayer.left + tempLayer.clip.width)) && (mouseY > tempLayer.top) && (mouseY < (tempLayer.top + tempLayer.clip.height)) ) { whichEl = tempLayer; } } if (whichEl == null) { return }; currentX = e.pageX; currentY = e.pageY; document.captureEvents(Event.MOUSEMOVE); document.onmousemove = moveEl; }

If the mousedown occurred in a draggable element, that element is assigned to whichEl. When the loop is finished, we check the value of whichEl. If whichEl is still null, no draggable element was found on the mousedown and the function returns. If an element was found, the function execution continues with the assignments to currentX and currentY, as before. We capture the mousemoves for the document and direct them to call moveEl.

The function to move one-of-many elements is exactly the same as that for a single element, except for the use of the whichEl variable.

    function moveEl(e) { distanceX = (e.pageX - currentX); distanceY = (e.pageY - currentY); currentX = e.pageX; currentY = e.pageY;
whichEl.moveBy(distanceX,distanceY); }

Our dropEl function is called on all mouseups, so we modify it to release the document's mousemove capture, and to assign a null value to whichEl, since no element is now being dragged.

    function dropEl() { document.releaseEvents(Event.MOUSEMOVE); whichEl = null; }

Try this code on our four squares below. What is different in their behavior from the similar example on the front page?

The present example does not have the dragged elements floating above the rest, which is usually the expected default behaviour in draggable windows, etc.

A couple more lines of code will do it, however

Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: Oct. 08, 1997
Revised: July 21, 1998

URL: http://www.webreference.com/dhtml/column6/dragLots.html

Justtechjobs.comFind a programming school near you

Online Campus Both