News:

Get Out, See Green!

Main Menu

Draggable HTML Elements (JavaScript)

Started by zourtney, Aug 22, 2009, 05:38 PM

Previous topic - Next topic

zourtney

I was working on some UI demos the other day and came across the need for draggable HTML elements. I quickly came across a good example on BrainJar. I wrote the thing up myself and thought I'd share it here (not that anyone will ever find it...)

I have written the thing up in slightly more detail, along with a fully functioning example here.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Drag Demo</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<style>
.dragBox
{
position: relative;
border: 1px dashed black;
}
</style>
<script type="text/javascript">
function Browser()
{
var ua, s, i;

ua = navigator.userAgent;

s = "MSIE";
if ( (i = ua.indexOf(s)) >= 0 )
{
this.isIE = true;
this.isNS = false;
this.version = parseFloat( ua.substr(i + s.length) );
return;
}

s = "Netscape6/";
if ( (i = ua.indexOf(s)) >= 0 )
{
this.isIE = false;
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.isIE = false;
this.isNS = true;
this.version = 6.1;
}
}

// create a global instance of the browser-info class.
var browser = new Browser();

// create a global drag object
var dragObj = new Object( );
dragObj.zIndex = 0;

function dragStart( event, elementId )
{
var element;
var x, y;

// if an element ID is being passed in, use that. Otherwise, try
// to find it based on what was clicked on.
if ( elementId )
{
dragObj.elementNode = document.getElementById( elementId );
}
else
{
if ( browser.isIE )
{
dragObj.elementNode = window.event.srcElement;
}
else
{
dragObj.elementNode = event.target;
}

// If this is a text node, use its parent
if ( dragObj.elementNode.nodeType == 3 )
{
dragObj.elementNode = dragObj.elementNode.parentNode;
}
}

// get the current cursor position, relative to the page
if ( browser.isIE )
{
x = window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop  + document.body.scrollTop;
}
else
{
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}

// save the current state to dragObj
dragObj.startCursorX = x;
dragObj.startCursorY = y;
dragObj.startElementX = parseInt( dragObj.elementNode.style.left, 10 );
dragObj.startElementY = parseInt( dragObj.elementNode.style.top,  10 );

if ( isNaN(dragObj.startElementX) )
dragObj.startElementX = 0;
if ( isNaN(dragObj.startElementY) )
dragObj.startElementY = 0;

// bring element to the top
dragObj.elementNode.style.zIndex = (++dragObj.zIndex);

// start event listeners on mousemove and mouseup
if ( browser.isIE )
{
document.attachEvent( "onmousemove", dragMove );
document.attachEvent( "onmouseup",   dragStop );
window.event.cancelBubble = true;
window.event.returnValue = false;
}
else
{
document.addEventListener( "mousemove", dragMove, true );
document.addEventListener( "mouseup",   dragStop, true );
event.preventDefault( );
}
}

function dragMove( event )
{
var x, y;

// get relative location
if ( browser.isIE )
{
x = window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop  + document.body.scrollTop;
}
else
{
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}

// move element
dragObj.elementNode.style.left = (dragObj.startElementX - dragObj.startCursorX + x) + "px";
dragObj.elementNode.style.top  = (dragObj.startElementY - dragObj.startCursorY + y) + "px";

// stop event
if ( browser.isIE )
{
window.event.cancelBubble = true;
window.event.returnValue = false;
}
else
{
event.preventDefault( );
}
}

function dragStop( event )
{
// remove the drag event listener
if ( browser.isIE )
{
document.detachEvent( "onmousemove", dragMove );
document.detachEvent( "onmouseup",   dragStop );
}
else
{
document.removeEventListener( "mousemove", dragMove, true );
document.removeEventListener( "mouseup",   dragStop, true );
}
}
</script>

</head>
<body>
Sometimes you might just want to input some
<span id="box1" class="dragBox" onmousedown="dragStart(event, 'box1');">movable</span>
text in the middle of a sentence. I don't know why, but you
<span id="box2" class="dragBox" onmousedown="dragStart(event, 'box2');">can!</span>
</body>
</html>