drag & drop + appendChild + Mozilla = problem

R

Ryan Stewart

If you don't want to read this post because of its length, I
understand. I've spent two and a half days on this problem and have a
good deal of information to relate. And this is kind of a long shot,
but I'm just hoping someone here has experienced a similar problem and
has a better idea of what's going on than I do.

First, I've tested this in IE 6.0, Netscape 7.2, Mozilla 1.75, and
Firefox 1.0. It works fine in IE (even though I was coding it in
Mozilla) but breaks in all the Mozilla based browsers. I'm using
youngpup's dom-drag script:
<http://www.youngpup.net/2001/domdrag>

(In fact, I've tried it with his original script, with a stripped down
version of it, and with my own version based on his concept.) This is
what I'm trying to accomplish:
1) Have some (two for now) "containers" on a page
2) Be able to drag the containers' children between containers
3) Actually change ownership of the children between containers in the
DOM (e.g. using appendChild)

My containers are div elements. The children are p elements. I've
eliminated all position detection from my code to simplify it. I have
one p element in container one. When it is dragged, no matter where it
is dropped, it is moved to container two by calling appendChild. The
dragging part works fine. When appendChild is called, the p element is
removed from container one and placed in container two, as expected.
However, immediately after the p element is placed in container two:
1) I cannot drag anything that should be draggable except for any
draggables in container one. This includes draggables in container two
and elsewhere in the page. After clicking the mouse anywhere in the
page, everything is again draggable that should be.
2) Almost any element in the page that has a cursor CSS property (such
as "cursor: pointer") does not display it properly. When you mouse over
one of these elements, the cursor remains as it is. Further, if you
move the cursor over some text, it does not change to the text
selection cursor. The only place that the cursor works is within
container one (where the element was dragged from).
3) The browser seems to think that one is on top of anything else. If
two is placed partially on top of one, then after the appendChild call,
even though two's "cursor" property doesn't work, one's "cursor"
property will work even if you place the mouse over some part of one
that is behind two. Also, if there is another draggable in one, you can
pick it up "through" container two. By this I mean that you can click
on two where one's draggable is behind it and begin dragging it.

One final point: the p element being dragged has text in it. If you
click and drag in the text somewhere, these problems do not occur. They
only happen when you drag the element by some of the blank space
surrounding the text.

Here is the shortest code sample I can come up with that demonstrates
the problem (I'm sorry I don't have access to any server that I could
post a URL for, and I'm afraid the indentation will be screwed up since
I'm posting this with Google):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=windows-1252">
<title>Dragging</title>
<script type="text/javascript">
var Drag = {

obj : null,

init : function(o) {
o.onmousedown = Drag.start;
o.onDragEnd = new Function();
},

start : function(e) {
e = Drag.fixE(e);
var o = Drag.obj = this;
o.lastMouseX = e.clientX;
o.lastMouseY = e.clientY;
document.onmousemove = Drag.drag;
document.onmouseup = Drag.end;
return false;
},

drag : function(e) {
e = Drag.fixE(e);
var o = Drag.obj;
var newX = parseInt(o.style.left) + e.clientX
- o.lastMouseX;
var newY = parseInt(o.style.top) + e.clientY
- o.lastMouseY;
Drag.obj.style.left = newX + "px";
Drag.obj.style.top = newY + "px";
Drag.obj.lastMouseX = e.clientX;
Drag.obj.lastMouseY = e.clientY;
return false;
},

end : function(e) {
e = Drag.fixE(e);
document.onmousemove = null;
document.onmouseup = null;
Drag.obj.onDragEnd(e.clientX, e.clientY);
Drag.obj = null;
},

fixE : function(e) {
if (typeof e == 'undefined') e = window.event;
return e;
}
};
</script>
<style type="text/css">
div.container { background-color: #bbb; position: absolute;
width: 100px; height: 200px; top: 50px; }
div.container h1 { cursor: move; }
div.container p.field { background-color: #eee;
border: 1px solid black; padding: 0 0.5ex;
position: relative; }
div#one { left: 50px; }
div#two { left: 250px; }
</style>
</head>
<body>
<div class="container" id="one">
<h1>
One
</h1>
<p class="field" id="harry" style="left: 0; top:
0;">Harry</p>
</div>
<div class="container" id="two">
<h1>
Two
</h1>
</div>
<div id="test" style="cursor: pointer; position: relative; top:
0; left: 0;">
test
</div>
<script type="text/javascript">
var two = document.getElementById("two");
var test = document.getElementById("test");
Drag.init(test);
var harry = document.getElementById("harry");
Drag.init(harry);
harry.onDragEnd = function(x, y) {
two.appendChild(harry);
harry.style.top = "0";
harry.style.left = "0";
}
</script>
</body>
</html>
 
R

Ryan Stewart

Here is a temporary URL:
http://24.171.2.56:8080/examples/dragDrop.jsp

And here is the properly formatted code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=windows-1252">
<title>Dragging</title>
<script type="text/javascript">
var Drag = {

obj : null,

init : function(o) {
o.onmousedown = Drag.start;
o.onDragEnd = new Function();
},

start : function(e) {
e = Drag.fixE(e);
var o = Drag.obj = this;
o.lastMouseX = e.clientX;
o.lastMouseY = e.clientY;
document.onmousemove = Drag.drag;
document.onmouseup = Drag.end;
return false;
},

drag : function(e) {
e = Drag.fixE(e);
var o = Drag.obj;
var newX = parseInt(o.style.left) + e.clientX
- o.lastMouseX;
var newY = parseInt(o.style.top) + e.clientY
- o.lastMouseY;
Drag.obj.style.left = newX + "px";
Drag.obj.style.top = newY + "px";
Drag.obj.lastMouseX = e.clientX;
Drag.obj.lastMouseY = e.clientY;
return false;
},

end : function(e) {
e = Drag.fixE(e);
document.onmousemove = null;
document.onmouseup = null;
Drag.obj.onDragEnd(e.clientX, e.clientY);
Drag.obj = null;
},

fixE : function(e) {
if (typeof e == 'undefined') e = window.event;
return e;
}
};
</script>
<style type="text/css">
div.container { background-color: #bbb; position: absolute;
width: 100px; height: 200px; top: 50px; }
div.container h1 { cursor: move; }
div.container p.field { background-color: #eee;
border: 1px solid black; padding: 0 0.5ex;
position: relative; }
div#one { left: 50px; }
div#two { left: 250px; }
</style>
</head>
<body>
<div class="container" id="one">
<h1>
One
</h1>
<p class="field" id="harry" style="left: 0; top: 0;">Harry</p>
</div>
<div class="container" id="two">
<h1>
Two
</h1>
</div>
<div id="test" style="cursor: pointer; position: relative; top: 0; left:
0;">
test
</div>
<script type="text/javascript">
var two = document.getElementById("two");
var test = document.getElementById("test");
Drag.init(test);
var harry = document.getElementById("harry");
Drag.init(harry);
harry.onDragEnd = function(x, y) {
two.appendChild(harry);
harry.style.top = "0";
harry.style.left = "0";
}
</script>
</body>
</html>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top