[2] | 1 | /*!
|
---|
| 2 | jquery.event.drag.js ~ v1.4 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
|
---|
| 3 | Liscensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
|
---|
| 4 | */
|
---|
| 5 | ;(function($){ // secure $ jQuery alias
|
---|
| 6 | /*******************************************************************************************/
|
---|
| 7 | // Created: 2008-06-04 | Updated: 2009-01-26
|
---|
| 8 | /*******************************************************************************************/
|
---|
| 9 | // Events: drag, dragstart, dragend
|
---|
| 10 | /*******************************************************************************************/
|
---|
| 11 |
|
---|
| 12 | // jquery method
|
---|
| 13 | $.fn.drag = function( fn1, fn2, fn3 ){
|
---|
| 14 | if ( fn2 ) this.bind('dragstart', fn1 ); // 2+ args
|
---|
| 15 | if ( fn3 ) this.bind('dragend', fn3 ); // 3 args
|
---|
| 16 | return !fn1 ? this.trigger('drag') // 0 args
|
---|
| 17 | : this.bind('drag', fn2 ? fn2 : fn1 ); // 1+ args
|
---|
| 18 | };
|
---|
| 19 |
|
---|
| 20 | // local refs
|
---|
| 21 | var $event = $.event, $special = $event.special,
|
---|
| 22 |
|
---|
| 23 | // special event configuration
|
---|
| 24 | drag = $special.drag = {
|
---|
| 25 | not: ':input', // don't begin to drag on event.targets that match this selector
|
---|
| 26 | distance: 0, // distance dragged before dragstart
|
---|
| 27 | which: 1, // mouse button pressed to start drag sequence
|
---|
| 28 | setup: function( data ){
|
---|
| 29 | data = $.extend({
|
---|
| 30 | distance: drag.distance,
|
---|
| 31 | which: drag.which,
|
---|
| 32 | not: drag.not
|
---|
| 33 | }, data || {});
|
---|
| 34 | data.distance = squared( data.distance ); // xイ + yイ = distanceイ
|
---|
| 35 | $event.add( this, "mousedown", handler, data );
|
---|
| 36 | },
|
---|
| 37 | teardown: function(){
|
---|
| 38 | $event.remove( this, "mousedown", handler );
|
---|
| 39 | if ( this === drag.dragging ) drag.dragging = drag.proxy = null; // deactivate element
|
---|
| 40 | selectable( this, true ); // enable text selection
|
---|
| 41 | }
|
---|
| 42 | };
|
---|
| 43 |
|
---|
| 44 | // handle drag-releatd DOM events
|
---|
| 45 | function handler ( event ){
|
---|
| 46 | var elem = this, returned, data = event.data || {};
|
---|
| 47 | // mousemove or mouseup
|
---|
| 48 | if ( data.elem ){
|
---|
| 49 | // update event properties...
|
---|
| 50 | elem = event.dragTarget = data.elem; // drag source element
|
---|
| 51 | event.dragProxy = drag.proxy || elem; // proxy element or source
|
---|
| 52 | event.cursorOffsetX = data.pageX - data.left; // mousedown offset
|
---|
| 53 | event.cursorOffsetY = data.pageY - data.top; // mousedown offset
|
---|
| 54 | event.offsetX = event.pageX - event.cursorOffsetX; // element offset
|
---|
| 55 | event.offsetY = event.pageY - event.cursorOffsetY; // element offset
|
---|
| 56 | }
|
---|
| 57 | // mousedown, check some initial props to avoid the switch statement
|
---|
| 58 | else if ( drag.dragging || ( data.which>0 && event.which!=data.which ) ||
|
---|
| 59 | $( event.target ).is( data.not ) ) return;
|
---|
| 60 | // handle various events
|
---|
| 61 | switch ( event.type ){
|
---|
| 62 | // mousedown, left click, event.target is not restricted, init dragging
|
---|
| 63 | case 'mousedown':
|
---|
| 64 | $.extend( data, $( elem ).offset(), {
|
---|
| 65 | elem: elem, target: event.target,
|
---|
| 66 | pageX: event.pageX, pageY: event.pageY
|
---|
| 67 | }); // store some initial attributes
|
---|
| 68 | $event.add( document, "mousemove mouseup", handler, data );
|
---|
| 69 | selectable( elem, false ); // disable text selection
|
---|
| 70 | return false; // prevents text selection in safari
|
---|
| 71 | // mousemove, check distance, start dragging
|
---|
| 72 | case !drag.dragging && 'mousemove':
|
---|
| 73 | if ( squared( event.pageX-data.pageX )
|
---|
| 74 | + squared( event.pageY-data.pageY ) // xイ + yイ = distanceイ
|
---|
| 75 | < data.distance ) break; // distance tolerance not reached
|
---|
| 76 | event.target = data.target; // force target from "mousedown" event (fix distance issue)
|
---|
| 77 | returned = hijack( event, "dragstart", elem ); // trigger "dragstart", return proxy element
|
---|
| 78 | if ( returned !== false ){ // "dragstart" not rejected
|
---|
| 79 | drag.dragging = elem; // activate element
|
---|
| 80 | drag.proxy = event.dragProxy = $( returned || elem )[0]; // set proxy
|
---|
| 81 | }
|
---|
| 82 | // mousemove, dragging
|
---|
| 83 | case 'mousemove':
|
---|
| 84 | if ( drag.dragging ){
|
---|
| 85 | returned = hijack( event, "drag", elem ); // trigger "drag"
|
---|
| 86 | if ( $special.drop ){ // manage drop events
|
---|
| 87 | $special.drop.allowed = ( returned !== false ); // prevent drop
|
---|
| 88 | $special.drop.handler( event ); // "dropstart", "dropend"
|
---|
| 89 | }
|
---|
| 90 | if ( returned !== false ) break; // "drag" not rejected, stop
|
---|
| 91 | event.type = "mouseup"; // helps "drop" handler behave
|
---|
| 92 | }
|
---|
| 93 | // mouseup, stop dragging
|
---|
| 94 | case 'mouseup':
|
---|
| 95 | $event.remove( document, "mousemove mouseup", handler ); // remove page events
|
---|
| 96 | if ( drag.dragging ) {
|
---|
| 97 | if ( $special.drop ) $special.drop.handler( event ); // "drop"
|
---|
| 98 | hijack( event, "dragend", elem ); // trigger "dragend"
|
---|
| 99 | } else {
|
---|
| 100 | hijack( event, "dragclickonly", elem );
|
---|
| 101 | }
|
---|
| 102 | selectable( elem, true ); // enable text selection
|
---|
| 103 | drag.dragging = drag.proxy = data.elem = null; // deactivate element
|
---|
| 104 | break;
|
---|
| 105 | }
|
---|
| 106 | };
|
---|
| 107 |
|
---|
| 108 | // set event type to custom value, and handle it
|
---|
| 109 | function hijack ( event, type, elem ){
|
---|
| 110 | event.type = type; // force the event type
|
---|
| 111 | var result = $event.handle.call( elem, event );
|
---|
| 112 | return result===false ? false : result || event.result;
|
---|
| 113 | };
|
---|
| 114 |
|
---|
| 115 | // return the value squared
|
---|
| 116 | function squared ( value ){ return Math.pow( value, 2 ); };
|
---|
| 117 |
|
---|
| 118 | // toggles text selection attributes
|
---|
| 119 | function selectable ( elem, bool ){
|
---|
| 120 | if ( !elem ) return; // maybe element was removed ?
|
---|
| 121 | elem.unselectable = bool ? "off" : "on"; // IE
|
---|
| 122 | elem.onselectstart = function(){ return bool; }; // IE
|
---|
| 123 | if ( document.selection && document.selection.empty ) document.selection.empty(); // IE
|
---|
| 124 | if ( elem.style ) elem.style.MozUserSelect = bool ? "" : "none"; // FF
|
---|
| 125 | };
|
---|
| 126 |
|
---|
| 127 | /*******************************************************************************************/
|
---|
| 128 | })( jQuery ); // confine scope |
---|