jQuery easy drag

9th January 2014

Sometimes it is nice to have a simple method that you can use on existing DOM elements to make them draggable. The Javascript below can be dropped into a file and used to make elements draggable. It supports dragging using touch too.

Javascript

Note: requires jQuery

//drag an element with some callbacks
function drag($elem, dragStartFunc, dragFunc, dragEndFunc) {
if (dragStartFunc===undefined || dragStartFunc===null) dragStartFunc = function() {};
if (dragFunc===undefined || dragFunc===null) dragFunc = function() {};
if (dragEndFunc===undefined || dragEndFunc===null) dragEndFunc = function() {};

$elem.on("selectstart", noEvent);

function noEvent() {
return false;
}

$elem.on("touchstart mousedown", function(e) {
var elem = this;

//merge the touch event with the regular event object
if (typeof e.originalEvent.touches !== "undefined" && e.originalEvent.touches.length) {
var touch = e.originalEvent.touches[0];
e.pageX = touch.pageX;
e.pageY = touch.pageY;
}

var mouseStart = {x: e.pageX, y: e.pageY};
var mouseDelta = {x: e.pageX, y: e.pageY};
var canceledClick = false;

$(document).on("touchmove mousemove", drag);
$(document).on("touchend mouseup mouseleave", cancelDrag);

dragStartFunc.call(elem, e);

function cancelDrag(e) {
if (canceledClick) {
setTimeout(function() {
$elem.off("click", noEvent);
}, 0);
}

$(document).off("touchmove mousemove", drag);
$(document).off("touchend mouseup mouseleave", cancelDrag);

//merge the touch event with the regular event object
if (typeof e.originalEvent.touches !== "undefined" && e.originalEvent.touches.length) {
var touch = e.originalEvent.touches[0];
e.pageX = touch.pageX;
e.pageY = touch.pageY;
}

dragEndFunc.call(elem, e);
}

function drag(e, delta) {
//merge the touch event with the regular event object
if (typeof e.originalEvent.touches !== "undefined" && e.originalEvent.touches.length) {
var touch = e.originalEvent.touches[0];
e.pageX = touch.pageX;
e.pageY = touch.pageY;
}

mouseDelta.x = e.pageX-mouseStart.x;
mouseDelta.y = e.pageY-mouseStart.y;

if (!canceledClick && (Math.abs(mouseDelta.x) > 0 || Math.abs(mouseDelta.y)>0)) {
$elem.on("click", noEvent);
canceledClick = true;
}

dragFunc.call(elem, e, mouseDelta);

return false;
}
});
}

Usage

The drag method above only triggers events and passes information to callback methods. It does not move any dom elements - it is up to you how you want things to be dragged. An example of moving a dom object with the mouse position is below:

//let the header be moved around freely
var startPos;

drag($("h1"), function(e) {
startPos = $(this).position();
$(this).css({ position: "absolute", left: startPos.x, top: startPos.y });
}, function(e, delta) {
$(this).css({ left: startPos.left + delta.x, top: startPos.top + delta.y });
}, function(e) {
console.log("dropped");
});

Make a comment

Contribute to this article and have your say.