I was working on our game when I needed to drag things around. Having included jQuery into the project I thought that'd be a fast win. Well, unless you also want to include that jQuery UI bloat, it's not. Having failed to find slim and simple "plugins", I wrote one myself. Took me all but 10 minutes.
Note that, as is usual with "plugins", this script serves my needs and my assumptions (most notably, it assumes the target element is positioned absolute). It's essentially worksforme-ware. Use it as your basis and build from there if you have to. Also note that it's really sloppy because it doesn't deregister events. Something I'll have to fix in a later version, I guess. See below
jQuery.prototype.draggable = function(){
var
$obj = this,
dragging = false,
startMouseX,
startMouseY,
startObjectX,
startObjectY;
// start drag
this.mousedown(function(e){
dragging = true;
startMouseX = e.pageX;
startMouseY = e.pageY;
var pos = $obj.offset();
startObjectX = pos.left;
startObjectY = pos.top;
});
// dragging
$(document).mousemove(function(e){
if (dragging) {
$obj.css({
left:startObjectX+(e.pageX-startMouseX)+'px',
top:startObjectY+(e.pageY-startMouseY)+'px'
});
}
});
// stop drag
$(document).mouseup(function(){
dragging = false;
});
return this;
};
The usage should be obvious (oh come on... $('#x').draggable();
). And don't bitch about prototype
. Learn it, love it, embrace it. You won't hear me do that "shorter" bullshit.
After some fiddling I've also created a somewhat more complex version, with event cleanup. The annoying part of it stores the undraggable method on the returned object. The issue with that is that the method will only exist on the returned object, not any new object you might get from jquery. The good news, though, is that the method is "context agnostic", meaning that you can just take it from the returned object and pass it around, without having to worry about scoping.
jQuery.prototype.draggable = function(){
var
$obj = this,
dragging = false,
startMouseX,
startMouseY,
startObjectX,
startObjectY;
ondragstart = function(e){
dragging = true;
startMouseX = e.pageX;
startMouseY = e.pageY;
var pos = $obj.offset();
startObjectX = pos.left;
startObjectY = pos.top;
},
ondragging = move = function(e){
if (dragging) {
$obj.css({
left:startObjectX+(e.pageX-startMouseX)+'px',
top:startObjectY+(e.pageY-startMouseY)+'px'
});
}
},
ondragstop = function(){
dragging = false;
};
// hook events
this.mousedown(ondragstart);
$(document)
.mousemove(ondragging)
.mouseup(ondragstop);
// unhook events, function is attached to returned object...
$obj.undraggable = function(){
$obj.unbind('mousedown',ondragstart);
$(document)
.unbind('mousemove',ondragging)
.unbind('mouseup',ondragstop);
delete $obj.undraggable;
ondragstart = ondragstop = ondragging = null;
return $obj;
};
return $obj;
};
Usage:
var $el = $('#target').draggable();
$el.click($el.undraggable().remove());
There. A jQuery draggable plugin in like 650 bytes, or 1k with cleanup. And that's unminified!
Hope it helps you!