Dragging a Div in jQuery - fine when mouse is slow, but fails on fast mouse movement

craic.com picture craic.com · Apr 22, 2011 · Viewed 15.9k times · Source

I want to drag a div around using my own jQuery code.

This example on jsfiddle works fine when the mouse movements are slow

http://jsfiddle.net/craic/kr7Un/

But any fast movement pulls the mouse out of the box and the tracking is lost.

jQuery UI draggable doesn't have this problem and tracks just fine regardless of how fast you move: http://jqueryui.com/demos/draggable/

But I want to roll my own simple version so that I can integrate it with Raphael, key presses, etc. I've looked at the jQuery UI draggable source but it is, for me, pretty impenetrable (800 lines).

I don't think it is an issue with event bubbling... any ideas?

Answer

James Montagne picture James Montagne · Apr 22, 2011

There are 2 issues. One is that you are canceling the drag when the mouse leaves the element, you don't want to do that. The 2nd is that the mousemove is only on box, once the cursor is out of the box it is no longer going to execute the mousemove. You can store the element which you are dragging and then add the mousemove to the entire page instead.

EDIT: Actually, I guess the mouseup should really also be on the document just in case you release the mouse click during a fast movement and your cursor is outside the box. Updated the jsfiddle.

See here:

http://jsfiddle.net/Jjgmz/1/

var box = $('#box');

box.offset({
    left: 100,
    top: 75
});

var drag = {
    elem: null,
    x: 0,
    y: 0,
    state: false
};
var delta = {
    x: 0,
    y: 0
};

box.mousedown(function(e) {
    if (!drag.state) {
        drag.elem = this;
        this.style.backgroundColor = '#f00';
        drag.x = e.pageX;
        drag.y = e.pageY;
        drag.state = true;
    }
    return false;
});


$(document).mousemove(function(e) {
    if (drag.state) {
        drag.elem.style.backgroundColor = '#f0f';

        delta.x = e.pageX - drag.x;
        delta.y = e.pageY - drag.y;

        $('#log').text(e.pageX + ' ' + e.pageY + ' ' + delta.x + ' ' + delta.y);

        var cur_offset = $(drag.elem).offset();

        $(drag.elem).offset({
            left: (cur_offset.left + delta.x),
            top: (cur_offset.top + delta.y)
        });

        drag.x = e.pageX;
        drag.y = e.pageY;
    }
});

$(document).mouseup(function() {
    if (drag.state) {
        drag.elem.style.backgroundColor = '#808';
        drag.state = false;
    }
});​