0

I'm trying to write a class for implementing visual drag and drop functionality in my webpage (yes I know there are some jquery plugins, I'm doing it for "fun").

All it has to do is to attach a mouse listener to a div element and move it when both mousedown and mousemove events are fired.

Everything seems to be fine, but when I drag the div more than one time, the script goes crazy.

This is the js I wrote:

var dnd;

function DragDrop (obj, horizontal, vertical) {
    dnd = this;
    this.obj = obj;
    this.horizontal = horizontal;
    this.vertical = vertical;
    obj.onmousedown = this.mouseDown;
    obj.onmouseup = this.mouseUp;
    obj.onmousemove = this.mouseMove;
}

DragDrop.prototype.mouseUp = function(e) {
    dnd.mousePressed = false;
};

DragDrop.prototype.mouseDown = function(e) {
    dnd.screenX = e.screenX;
    dnd.screenY = e.screenY;
    dnd.componentX = parseInt(dnd.obj.style.top);
    dnd.componentY = parseInt(dnd.obj.style.left);
    dnd.mousePressed = true;
};

DragDrop.prototype.mouseMove = function(e) {
    if(!dnd.mousePressed) return;

    if(dnd.horizontal) {
        var x = e.screenX;
        var deltaX = x - dnd.screenX;
        dnd.obj.style.left = dnd.componentX + deltaX + "px";
    }
    if(dnd.vertical) {
        var y = e.screenY;
        var deltaY = y - dnd.screenY;
        dnd.obj.style.top = dnd.componentY + deltaY + "px";
    }
}

And the HTML:

<div id="asd" style="position:absolute; top:50px; left:50px; background-color:black; color:white; padding: 10px; width:100px; height: 100px">
    DRAG ME
</div>

I initialize the DragDrop class as:

window.onload = function() {
    new DragDrop(document.getElementById("asd"), false, true);
}

So it moves the component horizontally only.

As I said, if you try to drag the component two or more times, the div starts placing in random positions.

What am I missing?

There also is a JSFiddle here if it helps

BackSlash
  • 21,927
  • 22
  • 96
  • 136

2 Answers2

1

Fixed it here - http://jsfiddle.net/yUQTf/1/

Problem :

DragDrop.prototype.mouseDown = function(e) {
    dnd.screenX = e.screenX;
    dnd.screenY = e.screenY;
    dnd.componentX = parseInt(dnd.obj.style.top); // This should be dnd.componentY
    dnd.componentY = parseInt(dnd.obj.style.left); // This should be dnd.componentX
    dnd.mousePressed = true;
};

Hope, it helps!

Cute_Ninja
  • 4,742
  • 4
  • 39
  • 63
1

You're X & Y's are crossed:

dnd.componentX = parseInt(dnd.obj.style.left);
dnd.componentY = parseInt(dnd.obj.style.top);

Here's a new fiddle: http://jsfiddle.net/yUQTf/2/

Also, just some advice as I've implemented drag and drop many times, you might find it a little cleaner to attach your mousemove and mouseup on to window. This will allow you to move off of the div and still have it drag, as well as lifting the mouse anywhere on your page to stop the drag:

window.addEventListener('mouseup', function(e){ dnd.mouseUp(e); });
window.addEventListener('mousemove', function(e){ dnd.mouseMove(e); });
rgthree
  • 7,217
  • 17
  • 21
  • Thank you! It was really a stupid mistake. Thanks for the event listener advice, I didn't know about that! – BackSlash May 02 '14 at 23:04