How to make a HTML object movable using behaviors
Published 09.09.2007. Last updated 10.09.2007
Introduction
For some time ago I was confronted with a bit of a problem: I had to make some simple
HTML components movable on web pages. Those web pages were part of a bigger intranet
solution distributed to customers running windows environment with Microsoft Internet
Explorer 6 or newer installed. Implementing this feature as a behavior was a direct
possibility since all customers where having IE preinstalled. Soon I discovered
that while it is relatively easy to make an object movable it can be a bit more
tricky to make it overlap over object especially if you are trying to overlap something
like dropdown box… I have spent hours on the internet trying to find a solution.
I could see that lots of other programmers were having similar problem but nobody
could come with more or less acceptable solution. Amongst others some were suggesting
rewriting dropdown box using DIV tags some where suggesting making
dropdown box invisible while moving objects above it. None of those suggestions
suited my needs. So I had to figure out solution on my own. And it seems to me that
I have found one. Here it is described in the article below. It is up to you to
judge whether it is good or not but I am using it a lot and I am pretty happy about
it.
Behaviors
Behaviors is quite a significant feature that was introduced in Microsoft Internet
Explorer 5.5. Dynamic HTML (DHTML) behaviors are components that encapsulate specific
functionality or behavior on a page. When applied to a standard HTML element on
a page, a behavior enhances that element's default behavior. An element behavior
enables you to add a custom element to pages. You can find more general information
about behaviors at Microsoft's web site here. Microsoft's web site provides us also with an example
of movable Behavior: here.
Implementing Behavior
I started out using above-mentioned Microsoft behavior. It introduced me to some
basic functionality. Some of it was good some was unnecessary for my so I ended
up rewriting it almost from scratch. Here you can see the minimal behavior needed
to make an object movable:
<attach event="onmouseup" handler="DoMouseUp" />
<attach event="onmousedown" handler="DoMouseDown" />
<script language="jscript">
var iOffsetX;
var iOffsetY;
function DoMouseDown()
{
setCapture();
iOffsetX = window.event.x - element.style.pixelLeft;
iOffsetY = window.event.y - element.style.pixelTop;
attachEvent ("onmousemove", DoMouseMove);
}
function DoMouseMove()
{
var iLeft = window.event.x - iOffsetX;
var iTop = window.event.y - iOffsetY;
style.left = iLeft;
style.top = iTop;
}
function DoMouseUp()
{
detachEvent ("onmousemove", DoMouseMove);
releaseCapture();
}
</script>
This behavior can be initiated by static HTML code like this:
<div id="movableDiv" style="position: absolute; width: 100px; height: 100px; background-color: Blue;
cursor: move; behavior: url(movable.htc); left: 100px; top: 100px;">
Movable DIV
</div>
Or dynamically by using JavaScript like this:
document.getElementById("movableDiv").style.behavior = "url(movable.htc)";
Let us now see how it works. First we will make a simple webpage like this:

If we will just move elements then it is not necessary tha we will get the desired
behavior...

But by adjusting z-index we might fix this problem:

Let us now add some SELECT objects and see what will happened then:

Well, not exactly what we wanted...

And finally here is the ultimate solution: we add underlying IFRAME object to our
DIV tag:
<attach event="onmouseup" handler="DoMouseUp" />
<attach event="onmousedown" handler="DoMouseDown" />
<attach event="ondocumentready" handler="SetDefaults" />
<script language="jscript">
var iOffsetX;
var iOffsetY;
var IFrElm;
var pDoc = document.parentWindow.document;
function SetDefaults()
{
IFrElm = makeIFrame();
}
function DoMouseDown()
{
if (IFrElm == null)
IFrElm = makeIFrame();
setCapture();
iOffsetX = window.event.x - element.style.pixelLeft;
iOffsetY = window.event.y - element.style.pixelTop;
attachEvent ("onmousemove", DoMouseMove);
}
function DoMouseMove()
{
var iLeft = window.event.x - iOffsetX;
var iTop = window.event.y - iOffsetY;
style.left = iLeft;
style.top = iTop;
IFrElm.style.left = iLeft;
IFrElm.style.top = iTop;
}
function DoMouseUp()
{
detachEvent ("onmousemove", DoMouseMove);
releaseCapture();
}
function makeIFrame()
{
var obj = pDoc.createElement('IFrame');
obj.style.position = 'absolute';
obj.style.left = offsetLeft;
obj.style.top = offsetTop;
obj.style.height = offsetHeight;
obj.style.width = offsetWidth;
obj.style.zIndex = style.zIndex - 1;
return pDoc.body.appendChild(obj);
}
</script>

|