/** * draggable - Class allows to make any element draggable * * Written by * Egor Khmelev (hmelyoff@gmail.com) * * Licensed under the MIT (MIT-LICENSE.txt). * * @author Egor Khmelev * @version 0.1.0-BETA ($Id$) * **/ (function( $ ){ function Draggable(){ this._init.apply( this, arguments ); }; Draggable.prototype.oninit = function(){ }; Draggable.prototype.events = function(){ }; Draggable.prototype.onmousedown = function(){ this.ptr.css({ position: "absolute" }); }; Draggable.prototype.onmousemove = function( evt, x, y ){ this.ptr.css({ left: x, top: y }); }; Draggable.prototype.onmouseup = function(){ }; Draggable.prototype.isDefault = { drag: false, clicked: false, toclick: true, mouseup: false }; Draggable.prototype._init = function(){ if( arguments.length > 0 ){ this.ptr = $(arguments[0]); this.outer = $(".draggable-outer"); this.is = {}; $.extend( this.is, this.isDefault ); var _offset = this.ptr.offset(); this.d = { left: _offset.left, top: _offset.top, width: this.ptr.width(), height: this.ptr.height() }; this.oninit.apply( this, arguments ); this._events(); } }; Draggable.prototype._getPageCoords = function( event ){ if( event.targetTouches && event.targetTouches[0] ){ return { x: event.targetTouches[0].pageX, y: event.targetTouches[0].pageY }; } else return { x: event.pageX, y: event.pageY }; }; Draggable.prototype._bindEvent = function( ptr, eventType, handler ){ var self = this; if( this.supportTouches_ ) ptr.get(0).addEventListener( this.events_[ eventType ], handler, false ); else ptr.bind( this.events_[ eventType ], handler ); }; Draggable.prototype._events = function(){ var self = this; this.supportTouches_ = 'ontouchend' in document; this.events_ = { "click": this.supportTouches_ ? "touchstart" : "click", "down": this.supportTouches_ ? "touchstart" : "mousedown", "move": this.supportTouches_ ? "touchmove" : "mousemove", "up" : this.supportTouches_ ? "touchend" : "mouseup" }; this._bindEvent( $( document ), "move", function( event ){ if( self.is.drag ){ event.stopPropagation(); event.preventDefault(); self._mousemove( event ); } }); this._bindEvent( $( document ), "down", function( event ){ if( self.is.drag ){ event.stopPropagation(); event.preventDefault(); } }); this._bindEvent( $( document ), "up", function( event ){ self._mouseup( event ); }); this._bindEvent( this.ptr, "down", function( event ){ self._mousedown( event ); return false; }); this._bindEvent( this.ptr, "up", function( event ){ self._mouseup( event ); }); this.ptr.find("a") .click(function(){ self.is.clicked = true; if( !self.is.toclick ){ self.is.toclick = true; return false; } }) .mousedown(function( event ){ self._mousedown( event ); return false; }); this.events(); }; Draggable.prototype._mousedown = function( evt ){ this.is.drag = true; this.is.clicked = false; this.is.mouseup = false; var _offset = this.ptr.offset(); var coords = this._getPageCoords( evt ); this.cx = coords.x - _offset.left; this.cy = coords.y - _offset.top; $.extend(this.d, { left: _offset.left, top: _offset.top, width: this.ptr.width(), height: this.ptr.height() }); if( this.outer && this.outer.get(0) ){ this.outer.css({ height: Math.max(this.outer.height(), $(document.body).height()), overflow: "hidden" }); } this.onmousedown( evt ); }; Draggable.prototype._mousemove = function( evt ){ this.is.toclick = false; var coords = this._getPageCoords( evt ); this.onmousemove( evt, coords.x - this.cx, coords.y - this.cy ); }; Draggable.prototype._mouseup = function( evt ){ var oThis = this; if( this.is.drag ){ this.is.drag = false; if( this.outer && this.outer.get(0) ){ if( $.browser.mozilla ){ this.outer.css({ overflow: "hidden" }); } else { this.outer.css({ overflow: "visible" }); } if( $.browser.msie && $.browser.version == '6.0' ){ this.outer.css({ height: "100%" }); } else { this.outer.css({ height: "auto" }); } } this.onmouseup( evt ); } }; window.Draggable = Draggable; })( jQuery );