www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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