jquery.event.drag-1.5.js (5992B)
1 /*! 2 jquery.event.drag.js ~ v1.5 ~ 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-03-24 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 dragging: false, // hold the active target element 29 setup: function( data ){ 30 data = $.extend({ 31 distance: drag.distance, 32 which: drag.which, 33 not: drag.not 34 }, data || {}); 35 data.distance = squared( data.distance ); // x² + y² = distance² 36 $event.add( this, "mousedown", handler, data ); 37 if ( this.attachEvent ) this.attachEvent("ondragstart", dontStart ); // prevent image dragging in IE... 38 }, 39 teardown: function(){ 40 $event.remove( this, "mousedown", handler ); 41 if ( this === drag.dragging ) drag.dragging = drag.proxy = false; // deactivate element 42 selectable( this, true ); // enable text selection 43 if ( this.detachEvent ) this.detachEvent("ondragstart", dontStart ); // prevent image dragging in IE... 44 } 45 }; 46 47 // prevent normal event binding... 48 $special.dragstart = $special.dragend = { setup:function(){}, teardown:function(){} }; 49 50 // handle drag-releatd DOM events 51 function handler ( event ){ 52 var elem = this, returned, data = event.data || {}; 53 // mousemove or mouseup 54 if ( data.elem ){ 55 // update event properties... 56 elem = event.dragTarget = data.elem; // drag source element 57 event.dragProxy = drag.proxy || elem; // proxy element or source 58 event.cursorOffsetX = data.pageX - data.left; // mousedown offset 59 event.cursorOffsetY = data.pageY - data.top; // mousedown offset 60 event.offsetX = event.pageX - event.cursorOffsetX; // element offset 61 event.offsetY = event.pageY - event.cursorOffsetY; // element offset 62 } 63 // mousedown, check some initial props to avoid the switch statement 64 else if ( drag.dragging || ( data.which>0 && event.which!=data.which ) || 65 $( event.target ).is( data.not ) ) return; 66 // handle various events 67 switch ( event.type ){ 68 // mousedown, left click, event.target is not restricted, init dragging 69 case 'mousedown': 70 $.extend( data, $( elem ).offset(), { 71 elem: elem, target: event.target, 72 pageX: event.pageX, pageY: event.pageY 73 }); // store some initial attributes 74 $event.add( document, "mousemove mouseup", handler, data ); 75 selectable( elem, false ); // disable text selection 76 drag.dragging = null; // pending state 77 return false; // prevents text selection in safari 78 // mousemove, check distance, start dragging 79 case !drag.dragging && 'mousemove': 80 if ( squared( event.pageX-data.pageX ) 81 + squared( event.pageY-data.pageY ) // x² + y² = distance² 82 < data.distance ) break; // distance tolerance not reached 83 event.target = data.target; // force target from "mousedown" event (fix distance issue) 84 returned = hijack( event, "dragstart", elem ); // trigger "dragstart", return proxy element 85 if ( returned !== false ){ // "dragstart" not rejected 86 drag.dragging = elem; // activate element 87 drag.proxy = event.dragProxy = $( returned || elem )[0]; // set proxy 88 } 89 // mousemove, dragging 90 case 'mousemove': 91 if ( drag.dragging ){ 92 returned = hijack( event, "drag", elem ); // trigger "drag" 93 if ( $special.drop ){ // manage drop events 94 $special.drop.allowed = ( returned !== false ); // prevent drop 95 $special.drop.handler( event ); // "dropstart", "dropend" 96 } 97 if ( returned !== false ) break; // "drag" not rejected, stop 98 event.type = "mouseup"; // helps "drop" handler behave 99 } 100 // mouseup, stop dragging 101 case 'mouseup': 102 $event.remove( document, "mousemove mouseup", handler ); // remove page events 103 if ( drag.dragging ){ 104 if ( $special.drop ) $special.drop.handler( event ); // "drop" 105 hijack( event, "dragend", elem ); // trigger "dragend" 106 } 107 selectable( elem, true ); // enable text selection 108 drag.dragging = drag.proxy = data.elem = false; // deactivate element 109 break; 110 } 111 return true; 112 }; 113 114 // set event type to custom value, and handle it 115 function hijack ( event, type, elem ){ 116 event.type = type; // force the event type 117 var result = $.event.handle.call( elem, event ); 118 return result===false ? false : result || event.result; 119 }; 120 121 // return the value squared 122 function squared ( value ){ return Math.pow( value, 2 ); }; 123 124 // suppress default dragstart IE events... 125 function dontStart(){ return ( drag.dragging === false ); }; 126 127 // toggles text selection attributes 128 function selectable ( elem, bool ){ 129 if ( !elem ) return; // maybe element was removed ? 130 elem.unselectable = bool ? "off" : "on"; // IE 131 elem.onselectstart = function(){ return bool; }; // IE 132 //if ( document.selection && document.selection.empty ) document.selection.empty(); // IE 133 if ( elem.style ) elem.style.MozUserSelect = bool ? "" : "none"; // FF 134 }; 135 136 /*******************************************************************************************/ 137 })( jQuery ); // confine scope