drag & drop + appendChild + Mozilla = problem

Discussion in 'Javascript' started by Ryan Stewart, Jan 13, 2005.

  1. Ryan Stewart

    Ryan Stewart Guest

    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>
    Ryan Stewart, Jan 13, 2005
    #1
    1. Advertising

  2. Ryan Stewart

    Ryan Stewart Guest

    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>
    Ryan Stewart, Jan 13, 2005
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Oliver Klein
    Replies:
    0
    Views:
    665
    Oliver Klein
    Aug 24, 2003
  2. Paul Tomblin
    Replies:
    1
    Views:
    804
    Paul Tomblin
    Nov 17, 2005
  3. Sebastian
    Replies:
    0
    Views:
    315
    Sebastian
    Nov 2, 2007
  4. Erik Terpstra
    Replies:
    2
    Views:
    162
    Erik Terpstra
    Apr 21, 2004
  5. Louis

    Mouse Drag-and-drop Problem

    Louis, Oct 16, 2007, in forum: Javascript
    Replies:
    2
    Views:
    116
    Thomas 'PointedEars' Lahn
    Oct 16, 2007
Loading...

Share This Page