// thanks once again to chris coyer for this wonderful snippet // edited to support touch events // www.riccardolardi.ch // http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui (function($) { $.fn.drags = function(opt) { opt = $.extend({ handle:"" }, opt); if(opt.handle === "") { var $el = this; } else { var $el = this.find(opt.handle); } return $el.on("mousedown touchstart", function(e) { if(opt.handle === "") { var $drag = $(this).addClass('draggable'); } else { var $drag = $(this).addClass('active-handle').parent().addClass('draggable'); } var z_idx = $drag.css('z-index'), drg_h = $drag.outerHeight(), drg_w = $drag.outerWidth(), pos_y = $drag.offset().top + drg_h - e.pageY || $drag.offset().top + drg_h - e.originalEvent.pageY, pos_x = $drag.offset().left + drg_w - e.pageX || $drag.offset().left + drg_w - e.originalEvent.pageX; $drag.css('z-index', z_idx).parents().on("mousemove touchmove", function(e) { $('.draggable').offset({ top: e.pageY + pos_y - drg_h || e.originalEvent.pageY + pos_y - drg_h, left: e.pageX + pos_x - drg_w || e.originalEvent.pageX + pos_x - drg_w }).on("mouseup touchend touchcancel", function() { $(this).removeClass('draggable'); }); }); e.preventDefault(); }).on("mouseup touchend touchcancel", function() { if(opt.handle === "") { $(this).removeClass('draggable'); } else { $(this).removeClass('active-handle').parent().removeClass('draggable'); } }); } })(jQuery);