jquery-ui/ui/jquery.ui.draggable.js

235 lines
5.5 KiB
JavaScript

/*
* jQuery UI Draggable 2.0.0
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Draggables
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
*/
(function( $, undefined ) {
$.widget("ui.draggable", {
widgetEventPrefix: "drag",
options: {
helper : false
},
drag_el : false, // either element or the helper
position : {},
offset : {},
_start_coords : {}, // start X/Y coords of mouse before drag
_start_position : {}, // start position of element before drag
_start_offset : {}, // start offset of element before drag
_create: function() {
this.scrollParent = this.element.scrollParent();
// Static position elements can't be moved with top/left
if ( this.element.css( "position" ) === "static" ) {
this.element.css( "position", "relative" );
}
// Prevent browser from hijacking drag
this.element.disableSelection();
// Using proxy to avoid anon functions using self to pass "this" along
this.element.bind( "mousedown." + this.widgetName, $.proxy( this._mouseDown, this ) );
}, // _create
destroy: function() {
return this;
}, // destroy
_setPosition : function() {
var left, top, position, css_position;
// Helper is appended to body so offset of element is all that's needed
if ( this.options.helper === true ) {
return this.element.offset();
}
css_position = this.drag_el.css( "position" );;
// If fixed or absolute
if ( css_position !== "relative" ) {
position = this.drag_el.position();
if ( css_position === "absolute" ) {
return position;
}
// Take into account scrollbar for fixed position
position.top = position.top - this.scrollParent.scrollTop();
position.left = position.left - this.scrollParent.scrollLeft();
return position;
} // css_position !+== absolute
/** When using relative, css values are checked **/
left = this.drag_el.css( "left" );
top = this.drag_el.css( "top" );
// Webkit will give back auto if there is nothing inline yet
left = ( left === "auto" ) ? 0 : parseInt( left, 10 );
top = ( top === "auto" ) ? 0 : parseInt( top, 10 );
return {
left : left,
top : top
};
}, // _setPosition
_mouseDown : function( event ) {
var el_position;
this.drag_el = this.element;
// Helper required, so clone, hide, and set reference
if ( this.options.helper === true ) {
this.drag_el = this.element.clone();
// If source element has an ID, change ID of helper to avoid overlap
if ( this.element.attr( 'id' ) ) {
this.drag_el
.css({
position : 'absolute',
display : 'none'
})
.disableSelection()
.attr( 'id', this.element.attr( 'id' ) + '-' + this.widgetName );
} // id
$('body').append( this.drag_el );
} // if this.options.helper = true
// Cache starting absolute and relative positions
this._start_position = this._setPosition();
this._start_offset = this.drag_el.offset();
// Cache current position and offset
this.position = $.extend( {}, this._start_position );
this.offset = $.extend( {}, this._start_offset );
this._start_coords = {
left : event.clientX,
top : event.clientY
};
this._trigger( "start", event );
$(document).bind( "mousemove." + this.widgetName, $.proxy( this._mouseMove, this ) );
$(document).bind( "mouseup." + this.widgetName, $.proxy( this._mouseUp, this ) );
// Set the helper up by actual element
if ( this.options.helper === true ) {
// get the absolute position of element so that helper will know where to go
el_offset = this.element.offset();
this.drag_el.css({
display : 'block',
top : el_offset.top + 'px',
left : el_offset.left + 'px'
});
} // this.options.height = true
}, // _mouseDown
_mouseMove : function( event ) {
var left_diff = event.clientX - this._start_coords.left,
top_diff = event.clientY - this._start_coords.top,
new_left = left_diff + this._start_position.left,
new_top = top_diff + this._start_position.top;
this.position = {
left : new_left,
top : new_top
};
// Refresh offset cache with new positions
this.offset.left = this._start_offset.left + new_left;
this.offset.top = this._start_offset.top + new_top;
this._trigger( "drag", event );
// User overriding left/top so shortcut math is no longer valid
if ( new_left !== this.position.left || new_top !== this.position.top ) {
// refresh offset using slower functions
this.offset = this.drag_el.offset();
}
this.drag_el.css({
left : this.position.left + 'px',
top : this.position.top + 'px'
});
}, // _mouseMove
_mouseUp : function( event ) {
this._trigger( "stop", event );
this._start_coords = {};
if ( this.options.helper === true ) {
this.drag_el.remove();
}
$(document).unbind( "mousemove." + this.widgetName );
$(document).unbind( "mouseup." + this.widgetName );
}, // _mouseUp
_trigger: function(type, event, ui) {
ui = ui || this._uiHash();
return $.Widget.prototype._trigger.call(this, type, event, ui);
}, // _trigger
_uiHash: function(event) {
return {
position : this.position,
offset : this.offset
};
} // _uiHash
});
$.extend($.ui.draggable, {
version: "2.0.0"
});
})(jQuery);