By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,007 Members | 1,232 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,007 IT Pros & Developers. It's quick & easy.

Draggable layers problem (IE only)

P: n/a
Hi, Folks!

I've been trying to develop my own version of these draggable
layers and I have been limiting myself to IE6...for now. I have
looked at some other examples to get ideas of creating an alternative
to pop-up windows in a web page. The code I have works (sort of).
The problem is that I can move these layers around when I move the
mouse slowly, however, if I move it fast the web browser looses track
of the motion and leaves the layer behind. If anyone has some ideas
or suggestions it would be much appreciated.

TIA

Here's my code:
=======================TEST2.HTM================== ==========

<HTML>

<HEAD>
</HEAD>

<script language="JavaScript" src="DivLayer.js"></script>
<script language="JavaScript" src="DateTime.js"></script>

<!-- BEGIN FLOATING LAYER CODE //-->
<div id="Test1" style="position:absolute;width:250px;left:50;top:5 0;visibility:hidden">
<!-- External table (i.e. the border) -->
<table border=0 width=250 bgcolor=Navy cellspacing=0
cellpadding=5>
<tr>
<td width=100%>
<table border=0 width=100% cellspacing=0 cellpadding=0
height=36>
<tr>
<!-- Title Bar -->
<td id="titleBar" style="cursor:move"
width="100%"
onMouseDown="divTest1.MouseDown();"
onMouseMove="divTest1.MouseMove();"
onMouseUp="divTest1.MouseUp();"
onMouseOut="divTest1.MouseOut();">
<font face=Arial color=#FFFFFF><B><I>Test
1</I></B></font>
</td>
<!-- The X in the upper right-hand corner to
close -->
<td id="closeX" style="cursor:hand" valign="top"
onClick="divTest1.ChangeState('hidden');">
<font color=#ffffff size=2 face=arial>
<B>X</B>
</font>
</td>
</tr>
<tr>
<!-- Window Contents -->
<td id="contents" width="100%" bgcolor="#FFFFFF"
style="padding:4px" colspan="2">
<!-- PLACE YOUR CONTENT HERE -->
This is where your content goes.<br>
It can be any html code or text.<br>
<input type="checkbox" name="myBox"
value="blah">Blah<BR>
<!-- END OF CONTENT AREA -->
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>

<div id="Test2" style="position:absolute;width:400;left:100;top:10 0;visibility:hidden">

<!-- Title Bar -->
<div id="titleBar"
style="cursor:move;padding:1;position:absolute;hei ght:15;width:385;left:0;top:0;background-color:Navy"
onMouseDown="divTest2.MouseDown();"
onMouseMove="divTest2.MouseMove();"
onMouseUp="divTest2.MouseUp();"
onMouseOut="divTest2.MouseOut();">
<font color=#ffffff size=1 face=arial>
<B><I>Test 2</I></B>
</font>
</div>

<!-- The X in the upper right-hand corner to close -->
<div id="closeX"
style="cursor:hand;padding:1;position:absolute;hei ght:15;width:15;left:385;top:0;background-color:Navy"
onClick="divTest2.ChangeState('hidden');">
<font color=#ffffff size=1 face=arial >
<CENTER><B>X</B></CENTER>
</font>
</div>

<!-- Window Contents -->
<div id="contents"
style="position:absolute;width:400;left:0;top:15;p adding:2;background-color:White;border-width:0
1 1 1;border-color:black;border-style:solid">
<!-- PLACE YOUR CONTENT HERE -->
<select name="lst_ContactList" size="1">
<option>DEFAULT</option>
<option>NOBODY</option>
<option>SOMEBODY</option>
<option>EVERYBODY</option>
<option>ANYBODY</option>
</select>
<BR>
Blah! Blah!<BR>
<!-- END OF CONTENT AREA -->
</div>
</div>

<div id="Test3" style="position:absolute;width:400;left:150;top:12 5;visibility:hidden">

<!-- Title Bar -->
<div id="titleBar"
style="cursor:move;padding:1;position:absolute;hei ght:18;width:382;left:0;top:0;background-color:Navy"
onMouseDown="divTest3.MouseDown();"
onMouseMove="divTest3.MouseMove();"
onMouseUp="divTest3.MouseUp();"
onMouseOut="divTest3.MouseOut();">
<font color=#ffffff size=2 face=arial>
<B><I>Test 3</I></B>
</font>
</div>

<!-- The X in the upper right-hand corner to close -->
<div id="closeX"
style="cursor:hand;padding:1;position:absolute;hei ght:18;width:18;left:382;top:0;background-color:Navy"
onClick="divTest3.ChangeState('hidden');">
<font color=#ffffff size=2 face=arial style="font-weight:bold"
<center>X</center>
</font>
</div>

<!-- Window Contents -->
<div id="contents"
style="position:absolute;width:400;left:0;top:18;p adding:2;background-color:White;border-width:0
1 1 1;border-color:black;border-style:solid">
<!-- PLACE YOUR CONTENT HERE -->
Main Entry: <b>byte</b> <BR>
Function: <i>noun</i> <BR>
A group of eight binary digits processed as a unit by a
computer and used especially to
represent an alphanumeric character.<br>
<!-- END OF CONTENT AREA -->
</div>
</div>

<div id="Test4" style="position:absolute;width:400;left:200;top:15 0;visibility:hidden">

<!-- Title Bar -->
<div id="titleBar"
style="cursor:move;padding:1;position:absolute;hei ght:20;width:380;left:0;top:0;background-color:Navy"
onMouseDown="divTest4.MouseDown();"
onMouseMove="divTest4.MouseMove();"
onMouseUp="divTest4.MouseUp();"
onMouseOut="divTest4.MouseOut();">
<font color=#ffffff size=3 face=arial>
<B><I>Test 4</I></B>
</font>
</div>

<!-- The X in the upper right-hand corner to close -->
<div id="closeX"
style="cursor:hand;padding:1;position:absolute;hei ght:20;width:20;left:380;top:0;background-color:Navy"
onClick="divTest4.ChangeState('hidden');">
<font color=#ffffff size=3 face=arial style="font-weight:bold" <center>X</center>
</font>
</div>

<!-- Window Contents -->
<div id="contents"
style="position:absolute;width:400;left:0;top:20;p adding:2;background-color:White;border-width:0
1 1 1;border-color:black;border-style:solid">
<!-- PLACE YOUR CONTENT HERE -->
Main Entry: <b>byte me</b><BR>
Function: <i>intransitive verb</i> <BR>
An expression used by peaved computers (i.e. the host) where
the current line of queries by other
computers (i.e. the client) leads to annoying the host
computer (e.g. network server).<br>
<!-- END OF CONTENT AREA -->
</div>
</div>

<div id="DateTime" style="position:absolute;width:450;left:200;top:20 0;visibility:hidden">

<!-- Title Bar -->
<div id="titleBar"
style="cursor:move;padding:1;position:absolute;hei ght:18;width:432;left:0;top:0;background-color:Navy"
onMouseDown="divDateTime.MouseDown();"
onMouseMove="divDateTime.MouseMove();"
onMouseUp="divDateTime.MouseUp();"
onMouseOut="divDateTime.MouseOut();">
<font color=#ffffff size=2 face=arial>
<B><I>Pick Time & Date</I></B>
</font>
</div>

<!-- The X in the upper right-hand corner to close -->
<div id="closeX"
style="cursor:hand;padding:1;position:absolute;hei ght:18;width:18;left:432;top:0;background-color:Navy"
onClick="divDateTime.ChangeState('hidden');">
<font color=#ffffff size=2 face=arial style="font-weight:bold" <center>X</center>
</font>
</div>

<!-- Window Contents -->
<div id="contents"
style="position:absolute;width:450;left:0;top:18;p adding:2;background-color:White;border-width:0
1 1 1;border-color:black;border-style:solid">
<!-- PLACE YOUR CONTENT HERE -->
<center>
<form name='frm_DateTimeSelect'>
<table border='0'>
<tr>
<td width='50%'>
<p align='center'>
<select name='lst_Month' size='1'></select>
<select name='lst_Date' size='1'></select>
/
<select name='lst_Year' size='1'></select>
</p>
</td>
<td width='25%'>
<p align='center'>
<select name='lst_Hour' size='1'></select>
:
<select name='lst_Minute' size='1'></select>
</p>
</td>
<td width='25%'>
<p align='center'>
<input type='radio' checked name='chk_AMPM'
value='AM'>AM
<input type='radio' name='chk_AMPM' value='PM'>PM
</p>
</td>
</tr>
<tr>
<td colspan='3'>
<p align='center'>
<input type='button' name='btn_OK' value=' OK
' onClick="divDateTime.ChangeState('hidden');saveDat eTime('frm_DateTimeSelect');">
</p>
</td>
</tr>
</table>
</form>
</center>
<!-- END OF CONTENT AREA -->
</div>
</div>

<div id="Date" style="position:absolute;width:350;left:150;top:22 5;visibility:hidden">

<!-- Title Bar -->
<div id="titleBar"
style="cursor:move;padding:1;position:absolute;hei ght:18;width:332;left:0;top:0;background-color:Navy"
onMouseDown="divDate.MouseDown();"
onMouseMove="divDate.MouseMove();"
onMouseUp="divDate.MouseUp();"
onMouseOut="divDate.MouseOut();">
<font color=#ffffff size=2 face=arial>
<B><I>Pick Date</I></B>
</font>
</div>

<!-- The X in the upper right-hand corner to close -->
<div id="closeX"
style="cursor:hand;padding:1;position:absolute;hei ght:18;width:18;left:332;top:0;background-color:Navy"
onClick="divDate.ChangeState('hidden');">
<font color=#ffffff size=2 face=arial style="font-weight:bold"

<center>X</center>
</font>
</div>

<!-- Window Contents -->
<div id="contents"
style="position:absolute;width:350;left:0;top:18;p adding:2;background-color:White;border-width:0
1 1 1;border-color:black;border-style:solid">
<!-- PLACE YOUR CONTENT HERE -->
<center>
<form name='frm_DateSelect'>
<table border='0'>
<tr>
<td width='50%'>
<p align='center'>
<select name='lst_Month' size='1'></select>
<select name='lst_Date' size='1'></select>
/
<select name='lst_Year' size='1'></select>
</p>
</td>
</tr>
<tr>
<td colspan='3'>
<p align='center'>
<input type='button' name='btn_OK' value=' OK
' onClick="divDate.ChangeState('hidden');saveDate('f rm_DateSelect');">
</p>
</td>
</tr>
</table>
</form>
</center>
<!-- END OF CONTENT AREA -->
</div>
</div>

<!-- END FLOATING LAYER CODE -->

<script language="JavaScript">
<!--
//Initialize the objects
divTest1 = new DivLayer('Test1');
divTest2 = new DivLayer('Test2');
divTest3 = new DivLayer('Test3');
divTest4 = new DivLayer('Test4');
divDateTime = new DivLayer('DateTime');
divDate = new DivLayer('Date');

function ArrayElements()
{
for(i = 0; i < document.all.length; i++)
{
top.ifrm_test.document.writeln("Item: "+ i +"<BR>");
top.ifrm_test.document.writeln("name: "+ document.all[i].name
+"<BR>");
top.ifrm_test.document.writeln("id: "+ document.all[i].id
+"<BR>");
top.ifrm_test.document.writeln("className: "+
document.all[i].className +"<BR>");
top.ifrm_test.document.writeln("title: "+
document.all[i].title +"<BR>");
top.ifrm_test.document.writeln("style: "+
document.all[i].style +"<BR>");
top.ifrm_test.document.writeln("tagName: "+
document.all[i].tagName +"<BR>");
top.ifrm_test.document.writeln("srcElement: "+
document.all[i].srcElement +"<BR>");
top.ifrm_test.document.writeln("parentElement: "+
document.all[i].parentElement +"<BR>");
top.ifrm_test.document.writeln("<BR>");
top.ifrm_test.document.writeln("<BR>");
}
}

//-->
</script>

<BODY>
<a href="javascript:divTest1.ChangeState('visible');" >Show Test 1
Window</a><BR>
<a href="javascript:divTest1.ChangeState('hidden');"> Hide Test 1
Window</a><BR>
<BR>
<a href="javascript:divTest2.ChangeState('visible');" >Show Test 2
Window</a><BR>
<a href="javascript:divTest2.ChangeState('hidden');"> Hide Test 2
Window</a><BR>
<BR>
<a href="javascript:divTest3.ChangeState('visible');" >Show Test 3
Window</a><BR>
<a href="javascript:divTest3.ChangeState('hidden');"> Hide Test 3
Window</a><BR>
<BR>
<a href="javascript:divTest4.ChangeState('visible');" >Show Test 4
Window</a><BR>
<a href="javascript:divTest4.ChangeState('hidden');"> Hide Test 4
Window</a><BR>

<form name="frm_Test">
<p><a href="javascript:divDateTime.ChangeState('visible' );populateDateTimeLists('frm_DateTimeSelect');setD ateOutput('frm_Test.txt_Test1');">Enter
Time & Date: </a>
&nbsp; <input type="text" name="txt_Test1" size=30></p><BR>
<p><a href="javascript:divDate.ChangeState('visible');po pulateDateLists('frm_DateSelect');setDateOutput('f rm_Test.txt_Test2');">Enter
Date: </a>
&nbsp; <input type="text" name="txt_Test2" size=30></p><BR>
</form>

<BR>
<BR>
<BR>
<BR>
<BR>
<a href="javascript:ArrayElements()">HTML Elements</a><BR>
<BR>
<iframe name="ifrm_test"></iframe>
</BODY>

</HTML>
======================DIVLAYER.JS================= =========

<!--
//Constructor for DivLayer object
function DivLayer(objName)
{
this.obj = eval("document.all." + objName); //div layer object
name
this.DivDragEnabled = false; //Boolean
this.zIndex = this.obj.style.zIndex; //zIndex property
this.ChangeState = DivLayer_changeState; //Methods
this.ResetZIndex = DivLayer_resetZIndex;
this.OnTop = DivLayer_onTop;
this.MouseDown = DivLayer_mouseDown;
this.MouseMove = DivLayer_mouseMove;
this.MouseUp = DivLayer_mouseUp;
this.MouseOut = DivLayer_mouseOut;
}

function DivLayer_resetZIndex()
{
this.obj.style.zIndex = 0;
}

function DivLayer_changeState(state)
{
this.obj.style.visibility = state;
this.ResetZIndex();
}

function DivLayer_onTop()
{
max = 0;

for(i = 0; i < document.all.length; i++)
{
if (document.all[i].tagName == "DIV")
max = (max < document.all[i].style.zIndex) ?
document.all[i].style.zIndex : max;
}
max++;
this.obj.style.zIndex = max;
}

function DivLayer_mouseDown(e)
{
//object which generated event
Src = event.srcElement;

//not titleBar object then re-assign srcElement = parentElement
(i.e. do nothing)
while (Src.id != "titleBar" && Src.tagName!= "BODY")
{
Src = Src.parentElement;
}

//selected object is titleBar then do the move!
if (Src.id == "titleBar")
{
offsetX = event.clientX;
offsetY = event.clientY;

nowX = parseInt(this.obj.style.left);
nowY = parseInt(this.obj.style.top);

this.OnTop(); //to bring
DivLayer on top of others
this.DivDragEnabled = true; //to enable
dragging
}
}

function DivLayer_mouseMove(e)
{
if (!this.DivDragEnabled) return;

this.obj.style.left = nowX + event.clientX - offsetX;
this.obj.style.top = nowY + event.clientY - offsetY;
}

function DivLayer_mouseUp(e)
{
this.DivDragEnabled = false;
}

function DivLayer_mouseOut(e)
{
this.DivDragEnabled = false;
}

//-->

======================DATETIME.JS================= =========

<!--

//global variable
oDateOutput = null;

function populateDateTimeLists(myForm)
{
//fill in values for drop-down lists.
var frm = eval("document."+ myForm);
var today = new Date(); //get time right now!!
//fill in year
var k = 0;
var min = today.getFullYear() - 5;
for(i = 0; i < 10; i++)
{//year array for -5/+5 years around current year.
k = min + i;
frm.lst_Year.options[i] = new Option(k, k);
}
frm.lst_Year.options[5].selected = true;
//fill in month
var Mnth = new Array('January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September', 'October', 'November',
'December');
for(i = 0; i < Mnth.length; i++)
{
frm.lst_Month.options[i] = new Option(Mnth[i], i);
}
frm.lst_Month.options[today.getMonth()].selected = true;
//fill in Day of Month
for(i = 0; i < 31; i++)
{
frm.lst_Date.options[i] = new Option(i + 1, i + 1);
}
frm.lst_Date.options[today.getDate() - 1].selected = true;
//fill in hour
for(i = 0; i < 12; i++)
{
frm.lst_Hour.options[i] = new Option(i + 1, i + 1);
}
k = parseInt(today.getHours());
if (k == 0)
{
frm.chk_AMPM[0].checked = true; //12 AM
frm.lst_Hour.options[11].selected = true;
}
if ((k >= 1) && (k <= 11))
{
frm.chk_AMPM[0].checked = true; //morning
frm.lst_Hour.options[k - 1].selected = true;
}
if (k == 12)
{
frm.chk_AMPM[1].checked = true; //12 PM
frm.lst_Hour.options[k - 1].selected = true;
}
if ((k >= 13) && (k <= 23))
{
frm.chk_AMPM[1].checked = true; //PM
frm.lst_Hour.options[k - 13].selected = true;
}
//fill in minutes
var Min = new Array(today.getMinutes(), 0, 5, 10, 15, 20, 25, 30,
35, 40, 45, 50, 55);
for(i = 0; i < Min.length; i++)
{
frm.lst_Minute.options[i] = new Option(Min[i], Min[i]);
}
frm.lst_Minute.options[0].selected = true;
}

function populateDateLists(myForm)
{
//fill in values for drop-down lists.
var frm = eval("document."+ myForm);
var today = new Date(); //get time right now!!
//fill in year
var k = 0;
var min = today.getFullYear() - 5;
//fill in year
for(i = 0; i < 10; i++)
{//year array for -5/+5 years around current year.
k = min + i;
frm.lst_Year.options[i] = new Option(k, k);
}
frm.lst_Year.options[5].selected = true;
//fill in month
var Mnth = new Array('January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September', 'October', 'November',
'December');
for(i = 0; i < Mnth.length; i++)
{
frm.lst_Month.options[i] = new Option(Mnth[i], i);
}
frm.lst_Month.options[today.getMonth()].selected = true;
//fill in Day of Month
for(i = 0; i < 31; i++)
{
frm.lst_Date.options[i] = new Option(i + 1, i + 1);
}
frm.lst_Date.options[today.getDate() - 1].selected = true;
}

function getDaysOfMonth(m, y)
{//use quotes for case statements...
switch(m)
{//month = 0 to 11
case '0': //January
return 31;
case '1': //Feb
if ((y % 4) == 0)
{
if ((y % 100) == 0 && (y % 400) != 0)
{
return 28;
}
return 29;
}
else
{
return 28;
}
case '2': //March
return 31;
case '3': //April
return 30;
case '4': //May
return 31;
case '5': //June
return 30;
case '6': //July
return 31;
case '7': //August
return 31;
case '8': //September
return 30;
case '9': //October
return 31;
case '10': //Nobember
return 30;
case '11': //December
return 31;
default: //invalid month
return 99;
}
}

function checkDoM(myForm)
{//check Day of Month
var frm = eval("document."+ myForm);
var m = frm.lst_Month.value;
var y = frm.lst_Year.value;
var max = getDaysOfMonth(m, y);
//Re-set selected date to proper last day-of-month if beyond the
maximum.
if (frm.lst_Date.value > max)
frm.lst_Date.options[max - 1].selected = true;
}

function setDateOutput(objName)
{
oDateOutput = eval("document."+ objName);
}

function saveDateTime(myForm)
{
var frm = eval("document."+ myForm);

checkDoM(myForm);
var tmp = parseInt(frm.lst_Month.value) + 1;
tmp = tmp.toString();
if (tmp.length == 1)
{//pad with a zero
tmp = '0' + tmp;
}
var selectedDate = tmp + '/';
tmp = frm.lst_Date.value;
if (tmp.length == 1)
{//pad with a zero
tmp = '0' + tmp;
}
selectedDate = selectedDate + tmp + '/' + frm.lst_Year.value + '
';
tmp = frm.lst_Hour.value;
selectedDate = selectedDate + tmp + ':';
tmp = frm.lst_Minute.value;
if (tmp.length == 1)
{//pad with a zero
tmp = '0' + tmp;
}
if(frm.chk_AMPM[0].checked == true)
selectedDate = selectedDate + tmp + ':00 ' +
frm.chk_AMPM[0].value;
else
selectedDate = selectedDate + tmp + ':00 ' +
frm.chk_AMPM[1].value;

//save to output
oDateOutput.value = selectedDate;
}

function saveDate(myForm)
{
var frm = eval("document."+ myForm);

checkDoM(myForm);
var tmp = parseInt(frm.lst_Month.value) + 1;
tmp = tmp.toString();
if (tmp.length == 1)
{
tmp = '0' + tmp;
}
var selectedDate = tmp + '/';
tmp = frm.lst_Date.value;
if (tmp.length == 1)
{
tmp = '0' + tmp;
}
selectedDate = selectedDate + tmp + '/' + frm.lst_Year.value;
//save to output
oDateOutput.value = selectedDate;
}
//-->
Jul 23 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
rdlebreton wrote:
The problem is that I can move these layers around when I move the
mouse slowly, however, if I move it fast the web browser looses track
of the motion and leaves the layer behind.
Well, I suppose that if you mouse your pointer too fast, the browser
cannot keep up with positioning the DIV fast enough, so the mouse moves
out of the div... mouseout event -> no more mousemove event:-)

What is usually done is to track the mouse position globally
(document.onmousemove sets global variables indicating the mouse
position), and use this position to drag the element, following the pattern:
- *startDrag*: on document mousedown, you determine if one of the target
in the event flow is to be dragged; if so, you initialize the drag
(pointer, timer) and start the next phase;
- *doDrag*: at regular intervals (using setInterval, or chaining
setTimeout calls), you get the global mouse position and you re-position
your layer accordingly;
- *stopDrag*: on document mouseup, you check whether there was an object
being dragged; if so, you clear the timer (using clearInterval) and
finalize the drag.
Here's my code:


It's far too big! Next time please present a trimmed version,
demonstrating clearly the issue.
Jul 23 '05 #2

P: n/a
Thanks for the suggestion, however...

How is it possible to switch the object in document.onmouseup, onmousedown,
onmouse move?

I tried using that method before and it worked great but only for one
DivLayer. I want to have it set up so that multiple DivLayers are on the
screen and can be moved.

Thanks.

A. Nonymous
(Yeah, yeah. I'm using a different identity.)

"Yann-Erwan Perio" <y-*******@em-lyon.com> wrote in message
news:40***********************@news.free.fr...
rdlebreton wrote:
The problem is that I can move these layers around when I move the
mouse slowly, however, if I move it fast the web browser looses track
of the motion and leaves the layer behind.
Well, I suppose that if you mouse your pointer too fast, the browser
cannot keep up with positioning the DIV fast enough, so the mouse moves
out of the div... mouseout event -> no more mousemove event:-)

What is usually done is to track the mouse position globally
(document.onmousemove sets global variables indicating the mouse
position), and use this position to drag the element, following the

pattern: - *startDrag*: on document mousedown, you determine if one of the target
in the event flow is to be dragged; if so, you initialize the drag
(pointer, timer) and start the next phase;
- *doDrag*: at regular intervals (using setInterval, or chaining
setTimeout calls), you get the global mouse position and you re-position
your layer accordingly;
- *stopDrag*: on document mouseup, you check whether there was an object
being dragged; if so, you clear the timer (using clearInterval) and
finalize the drag.
Here's my code:


It's far too big! Next time please present a trimmed version,
demonstrating clearly the issue.

Jul 23 '05 #3

P: n/a
A. Nonymous wrote:

[about dragging elements]
I tried using that method before and it worked great but only for one
DivLayer. I want to have it set up so that multiple DivLayers are on the
screen and can be moved.


Well, since you're aware of the technique, then it's a conception
problem, but without knowing the specifics of your application, it's
hard to provide you with sound advice.

Here's a simple example (slightly tested only) illustating how to move
several elements at the same time, using (1) a callback function and (2)
a nested structure. However, if your application really requires by
essence to have many objects moved at the same time, then it might be
better to use an intermediate custom-object which would hold the
collection of movable objects, with some possible kind of dynamic
reflection on the HTML.
<style type="text/css">
div{position:absolute;width:100px;height:100px}
div div{left:50px;top:50px;}
div#drgdv0{top:10px;left:10px;background:#f00}
div#drgdv1{top:150px;left:150px;background:#0f0}
div#drgdv2{top:300px;left:300px;background:#00f}
</style>

<script type="text/javascript">
var makeDraggable = (function() {
var allDrgObj=[];
var Mouse={x:0, y:0};
var drgObj=null;

function _e(obj, evt, func){
if(obj[evt]) {
obj[evt]=(function(oldf){
return function(){
func.apply(this, arguments);
return oldf.apply(this, arguments);
}
})(obj[evt]);
} else { obj[evt]=func; }
}

_e(document, "onmousedown",
function(evt) {
var el;
evt=evt||window.event;
for(var el=evt.target||evt.srcElement;el;el=el.parentNode) {
if(el.nodeType==1){
for(var ii=0; ii<allDrgObj.length; ii++){
if(el==allDrgObj[ii].element) {
drgObj=allDrgObj[ii]
startDrag();
return;
}}}}
}
);

_e(document, "onmouseup",
function(evt) { stopDrag(); }
);

_e(document, "onmousemove",
function(evt) {
evt=evt||window.event;
Mouse.x=evt.clientX||evt.pageX||0;
Mouse.y=evt.clientY||evt.pageY||0;
}
);

function startDrag(){
setTimeout(
(function(){
var oldx=Mouse.x, oldy=Mouse.y;
return function(){
if(drgObj){
//asumption here: don't nest your draggable divs
//into absolutely positioned elements,
//or more code is required
var el=drgObj.element,
x=parseInt(el.style.left,10)||el.offsetLeft||0,
y=parseInt(el.style.top,10)||el.offsetTop||0,
offX=Mouse.x-oldx,
offY=Mouse.y-oldy;

el.style.left=(x+offX)+"px";
el.style.top=(y+offY)+"px";
oldx=Mouse.x;
oldy=Mouse.y;

if(typeof drgObj.callback=="function")
drgObj.callback.call(el,{offsetX:offX,offsetY:offY });

setTimeout(arguments.callee, 40);
}
}
})(),
40
);
}

function stopDrag(){ drgObj=null; }

return function (el, cbk){
var d=document;
if(el &&
el.nodeType &&
typeof el.parentNode!="undefined" &&
typeof Function.prototype!="undefined" &&
typeof Function.prototype.apply!="undefined") {
allDrgObj.push({element:el,callback:cbk});
}
}
})();
</script>

<div id="drgdv0"><div style="background:#0ff;"></div></div>
<div id="drgdv1"><div style="background:#f0f;"></div></div>
<div id="drgdv2"><div style="background:#ff0;"></div></div>

<script type="text/javascript">
window.onload=function(evt){
if(document.getElementById){
makeDraggable(document.getElementById("drgdv0"), mngr);
makeDraggable(document.getElementById("drgdv1"), mngr);
makeDraggable(document.getElementById("drgdv2"), mngr);
}
}

function mngr(pos){
for(var div, ii=0; ii<3; ii++){
div=document.getElementById("drgdv"+ii);
if(this.id!=div.id){
div.style.left=
((parseInt(div.style.left,10)||
div.offsetLeft||0)+ii*pos.offsetX)+"px";
div.style.top=
((parseInt(div.style.top,10)||
div.offsetTop||0)+ii*pos.offsetY)+"px";
}
}
}
</script>
Regards,
Yep.
Jul 23 '05 #4

P: n/a
rdlebreton wrote:
I've been trying to develop my own version of these draggable
layers and I have been limiting myself to IE6...for now.
IE is probably one of the worst browsers to do primary development on.
It is so error tolerant, and supports so many non-standard methods that
what works on IE often will not work on browsers that are actually
equally dynamic and capable (at least in the area of DHTML). Working
with IE may tend to give the script author the impression that it is a
lot of work to create cross-browser scripts, while developing on a
browser that implements W3C DOM standard methods, but is intolerant of
errors, will usually result in code that also works on IE, along with
all other browsers that implement those methods.
I have
looked at some other examples to get ideas of creating an alternative
to pop-up windows in a web page. The code I have works (sort of).
The problem is that I can move these layers around when I move the
mouse slowly, however, if I move it fast the web browser looses track
of the motion and leaves the layer behind.
Yep has already pointed out why that happens. It is rarely possible to
animate a DIV sufficiently quickly or accurately to genuinely follow
mouse movements over that DIV. Instead following mouse movements at the
document level is more practical, but mouse movements events at that
level are to quick to allow any animation to directly follow from those
events, so the actual animation has to be done by a method that uses
setTimeout or setInterval.
If anyone has some ideas
or suggestions it would be much appreciated.
Well, suggestions must include more considered z-index handling. And
positioning DIVs that contain form controls suffers from the problem
that some controls cannot be covered by a DIV on some browsers, which
suggests that DIVs such controls might some measure to hide those
controls when their DIV is covered with another, so some sort of
detection of overlapping DIVs.

<snip> <script language="JavaScript" src="DivLayer.js"></script>
Valid Html 4 requires opening script tags to include a type attribute,
which, once provided, renders the deprecated language attribute
redundant.
<script language="JavaScript" src="DateTime.js"></script>
The Date script does not appear to have any baring on the problem.

<snip> <td id="titleBar" style="cursor:move" <snip> <div id="titleBar" <snip> <div id="titleBar" <snip>

ID attributes are supposed to be unique within a document.

Recently I have been investigating using DIVs as an alternative for
tasks that are often attempted with new windows (because of the
irresolvable pop-up blocking problem) so I thought I would have a look
at your script, and have a go at re-implementing it to do what you
wanted. The results are to big to post so I have made them available
on-line at:-

<URL: http://www.litotes.demon.co.uk/examp...iWindow_1.html

(Note: don't expect this file to be available for more than a week or
two.)

- it could still stand some more work, and more general testing (I have
only tired it with windows versions of Opera, Mozilla and IE so far) but
might be worth a look.

Richard.
Jul 23 '05 #5

P: n/a
1st reaction:

I like what you've done with the code. You've practically done
everything I was trying to do.

2nd reaction:

Wow! That's a lot of code and a lot more about JavaScript that I don't
understand. It is going to take me a while to wrap my brain around that.

This was really for an Intranet site. Everyone here uses IE but
learning the in's and out's of NN and Opera I'm sure is a good thing. I
kept looking and looking at different examples of draggable layers and could
not wrap my brain around them because they were so complex. I kept thinking
there has GOT to be an easier way to do this (e.g. avoiding
document.onMouseMove, etc). Obviously, I was wrong.
"Richard Cornford" <Ri*****@litotes.demon.co.uk> wrote in message
news:c5*******************@news.demon.co.uk...

<big snip>
<URL: http://www.litotes.demon.co.uk/examp...iWindow_1.html

(Note: don't expect this file to be available for more than a week or
two.)

- it could still stand some more work, and more general testing (I have
only tired it with windows versions of Opera, Mozilla and IE so far) but
might be worth a look.

Richard.

Jul 23 '05 #6

P: n/a
Just as a foot note:

I have added onSelectStart = "return false;" to the titleBar in my example
and that seems to clean up some of the strange behaviour. However, using
the document.onmousemove, up, down, etc. would be the best way to go because
the animation / moving is cleaner...I just can't wrap my brain around that
code right now.

:P
Jul 23 '05 #7

P: n/a
A. Nonymous wrote:
I just can't wrap my brain around that
code right now.


Javascript can be coded in different flavors, and Richard's using at
perfection a particular coding style which is very powerful, but
(unfortunately) not well known - closures-based style. As such, it can
be quite obscure when you encounter it the first time.

An excellent introduction has been written recently by Mr Cornford on
this subject; though quite technical, it is well-structured and
detailed. If I may suggest, give it a chance; you'll probably find some
useful analytical axis which could help you into understanding the
script he's provided.

<URL:http://www.jibbering.com/faq/faq_notes/closures.html>
Regards,
Yep.
Jul 23 '05 #8

P: n/a
On Mon, 12 Apr 2004 23:00:19 +0100, "Richard Cornford"
<Ri*****@litotes.demon.co.uk> wrote:
<URL: http://www.litotes.demon.co.uk/examp...iWindow_1.html

(Note: don't expect this file to be available for more than a week or
two.)

Feel free to use http://jibbering.com/2004/04/etc. (as you have a log
in anyway) if you want to maintain things longer, I'm also willing to
create a js.jibbering.com or similar for maintaining resources.

I feel it's important that things mentioned have legs!

Jim.
--
comp.lang.javascript FAQ - http://jibbering.com/faq/

Jul 23 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.