Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Adding touch support, dropping live support

  • Loading branch information...
commit b0bafd0226706ec5156925ebf3af6a8d0aedb8a1 1 parent 9d0c7c6
authored

Showing 1 changed file with 67 additions and 65 deletions. Show diff stats Hide diff stats

  1. 132  event.drag/jquery.event.drag.js
132  event.drag/jquery.event.drag.js 100644 → 100755
... ...
@@ -1,10 +1,10 @@
1 1
 /*! 
2  
- * jquery.event.drag - v 2.0.0 
  2
+ * jquery.event.drag - v 2.1.0 
3 3
  * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
4 4
  * Open Source MIT License - http://threedubmedia.com/code/license
5 5
  */
6 6
 // Created: 2008-06-04 
7  
-// Updated: 2010-06-07
  7
+// Updated: 2010-09-15
8 8
 // REQUIRES: jquery 1.4.2+
9 9
 
10 10
 ;(function( $ ){
@@ -43,10 +43,7 @@ drag = $special.drag = {
43 43
 	
44 44
 	// the key name for stored drag data
45 45
 	datakey: "dragdata",
46  
-	
47  
-	// the namespace for internal live events
48  
-	livekey: "livedrag",
49  
-	
  46
+		
50 47
 	// count bound related events
51 48
 	add: function( obj ){ 
52 49
 		// read the interaction data
@@ -55,11 +52,6 @@ drag = $special.drag = {
55 52
 		opts = obj.data || {};
56 53
 		// count another realted event
57 54
 		data.related += 1;
58  
-		// bind the live "draginit" delegator
59  
-		if ( !data.live && obj.selector ){
60  
-			data.live = true;
61  
-			$event.add( this, "draginit."+ drag.livekey, drag.delegate );
62  
-		}
63 55
 		// extend data options bound with this event
64 56
 		// don't iterate "opts" in case it is a node 
65 57
 		$.each( drag.defaults, function( key, def ){
@@ -83,7 +75,7 @@ drag = $special.drag = {
83 75
 		// store the interaction data
84 76
 		$.data( this, drag.datakey, data );
85 77
 		// bind the mousedown event, which starts drag interactions
86  
-		$event.add( this, "mousedown", drag.init, data );
  78
+		$event.add( this, "touchstart mousedown", drag.init, data );
87 79
 		// prevent image dragging in IE...
88 80
 		if ( this.attachEvent ) 
89 81
 			this.attachEvent("ondragstart", drag.dontstart ); 
@@ -97,9 +89,7 @@ drag = $special.drag = {
97 89
 		// remove the stored data
98 90
 		$.removeData( this, drag.datakey );
99 91
 		// remove the mousedown event
100  
-		$event.remove( this, "mousedown", drag.init );
101  
-		// remove the "live" delegation
102  
-		$event.remove( this, "draginit", drag.delegate );
  92
+		$event.remove( this, "touchstart mousedown", drag.init );
103 93
 		// enable text selection
104 94
 		drag.textselect( true ); 
105 95
 		// un-prevent image dragging in IE...
@@ -108,11 +98,14 @@ drag = $special.drag = {
108 98
 	},
109 99
 		
110 100
 	// initialize the interaction
111  
-	init: function( event ){
  101
+	init: function( event ){ 
  102
+		// sorry, only one touch at a time
  103
+		if ( drag.touched ) 
  104
+			return;
112 105
 		// the drag/drop interaction data
113 106
 		var dd = event.data, results;
114 107
 		// check the which directive
115  
-		if ( dd.which > 0 && event.which != dd.which ) 
  108
+		if ( event.which != 0 && dd.which > 0 && event.which != dd.which ) 
116 109
 			return; 
117 110
 		// check for suppressed selector
118 111
 		if ( $( event.target ).is( dd.not ) ) 
@@ -120,8 +113,14 @@ drag = $special.drag = {
120 113
 		// check for handle selector
121 114
 		if ( dd.handle && !$( event.target ).closest( dd.handle, event.currentTarget ).length ) 
122 115
 			return;
  116
+
123 117
 		// store/reset some initial attributes
  118
+		if ( event.type == "touchstart" ){
  119
+			drag.touched = this;
  120
+			drag.touchFix( event, dd );
  121
+		}
124 122
 		dd.propagates = 1;
  123
+		dd.mousedown = this;
125 124
 		dd.interactions = [ drag.interaction( this, dd ) ];
126 125
 		dd.target = event.target;
127 126
 		dd.pageX = event.pageX;
@@ -149,27 +148,49 @@ drag = $special.drag = {
149 148
 		// disable text selection
150 149
 		drag.textselect( false ); 
151 150
 		// bind additional events...
152  
-		$event.add( document, "mousemove mouseup", drag.handler, dd );
153  
-		// helps prevent text selection
154  
-		return false;
  151
+		if ( drag.touched )
  152
+			$event.add( drag.touched, "touchmove touchend", drag.handler, dd );
  153
+		else 
  154
+			$event.add( document, "mousemove mouseup", drag.handler, dd );
  155
+		// helps prevent text selection or scrolling
  156
+		if ( !drag.touched || dd.live )
  157
+			return false;
155 158
 	},	
  159
+	
  160
+	// fix event properties for touch events
  161
+	touchFix: function( event, dd ){
  162
+		var orig = event.originalEvent, i = 0;
  163
+		// iOS webkit: touchstart, touchmove, touchend
  164
+		if ( orig && orig.changedTouches ){ 
  165
+			event.pageX = orig.changedTouches[0].pageX;
  166
+			event.pageY = orig.changedTouches[0].pageY;	
  167
+		}
  168
+		//console.log( event.type, event );
  169
+	},
  170
+	
156 171
 	// returns an interaction object
157 172
 	interaction: function( elem, dd ){
  173
+		var offset = $( elem )[ dd.relative ? "position" : "offset" ]() || { top:0, left:0 };
158 174
 		return {
159 175
 			drag: elem, 
160 176
 			callback: new drag.callback(), 
161 177
 			droppable: [],
162  
-			offset: $( elem )[ dd.relative ? "position" : "offset" ]() || { top:0, left:0 }
  178
+			offset: offset
163 179
 		};
164 180
 	},
  181
+	
165 182
 	// handle drag-releatd DOM events
166 183
 	handler: function( event ){ 
167 184
 		// read the data before hijacking anything
168 185
 		var dd = event.data;
  186
+		if ( drag.touched )
  187
+			drag.touchFix( event, dd );		
169 188
 		// handle various events
170 189
 		switch ( event.type ){
171 190
 			// mousemove, check distance, start dragging
172  
-			case !dd.dragging && 'mousemove': 
  191
+			case !dd.dragging && 'touchmove': 
  192
+				event.preventDefault();
  193
+			case !dd.dragging && 'mousemove':
173 194
 				//  drag tolerance, x² + y² = distance²
174 195
 				if ( Math.pow(  event.pageX-dd.pageX, 2 ) + Math.pow(  event.pageY-dd.pageY, 2 ) < Math.pow( dd.distance, 2 ) ) 
175 196
 					break; // distance tolerance not reached
@@ -178,71 +199,42 @@ drag = $special.drag = {
178 199
 				if ( dd.propagates ) // "dragstart" not rejected
179 200
 					dd.dragging = true; // activate interaction
180 201
 			// mousemove, dragging
181  
-			case 'mousemove': 
  202
+			case 'touchmove':
  203
+				event.preventDefault();
  204
+			case 'mousemove':
182 205
 				if ( dd.dragging ){
183 206
 					// trigger "drag"		
184 207
 					drag.hijack( event, "drag", dd );
185 208
 					if ( dd.propagates ){
186 209
 						// manage drop events
187 210
 						if ( dd.drop !== false && $special.drop )
188  
-							$special.drop.handler( event, dd ); // "dropstart", "dropend"
  211
+							$special.drop.handler( event, dd ); // "dropstart", "dropend"							
189 212
 						break; // "drag" not rejected, stop		
190 213
 					}
191 214
 					event.type = "mouseup"; // helps "drop" handler behave
192 215
 				}
193 216
 			// mouseup, stop dragging
  217
+			case 'touchend': 
194 218
 			case 'mouseup': 
195  
-				$event.remove( document, "mousemove mouseup", drag.handler ); // remove page events
  219
+				if ( drag.touched )
  220
+					$event.remove( drag.touched, "touchmove touchend", drag.handler ); // remove touch events
  221
+				else 
  222
+					$event.remove( document, "mousemove mouseup", drag.handler ); // remove page events	
196 223
 				if ( dd.dragging ){
197 224
 					if ( dd.drop !== false && $special.drop ) 
198 225
 						$special.drop.handler( event, dd ); // "drop"
199 226
 					drag.hijack( event, "dragend", dd ); // trigger "dragend"	
200 227
 					}
201 228
 				drag.textselect( true ); // enable text selection
202  
-				
203 229
 				// if suppressing click events...
204 230
 				if ( dd.click === false && dd.dragging ){
205  
-					jQuery.event.triggered = true;
206  
-					setTimeout(function(){
207  
-						jQuery.event.triggered = false;
208  
-					}, 20 );
209  
-				dd.dragging = false; // deactivate element	
  231
+					$.data( dd.mousedown, "suppress.click", new Date().getTime() + 5 );
210 232
 				}
  233
+				dd.dragging = drag.touched = false; // deactivate element	
211 234
 				break;
212 235
 		}
213 236
 	},
214  
-	
215  
-	// identify potential delegate elements
216  
-	delegate: function( event ){
217  
-		// local refs
218  
-		var elems = [], target, 
219  
-		// element event structure
220  
-		events = $.data( this, "events" ) || {};
221  
-		// query live events
222  
-		$.each( events.live || [], function( i, obj ){
223  
-			// no event type matches
224  
-			if ( obj.preType.indexOf("drag") !== 0 )
225  
-				return;
226  
-			// locate the element to delegate
227  
-			target = $( event.target ).closest( obj.selector, event.currentTarget )[0];
228  
-			// no element found
229  
-			if ( !target ) 
230  
-				return;
231  
-			// add an event handler
232  
-			$event.add( target, obj.origType+'.'+drag.livekey, obj.origHandler, obj.data );
233  
-			// remember new elements
234  
-			if ( $.inArray( target, elems ) < 0 )
235  
-				elems.push( target );		
236  
-		});
237  
-		// if there are no elements, break
238  
-		if ( !elems.length ) 
239  
-			return false;
240  
-		// return the matched results, and clenup when complete		
241  
-		return $( elems ).bind("dragend."+ drag.livekey, function(){
242  
-			$event.remove( this, "."+ drag.livekey ); // cleanup delegation
243  
-		});
244  
-	},
245  
-	
  237
+		
246 238
 	// re-use event object for custom events
247 239
 	hijack: function( event, type, dd, x, elem ){
248 240
 		// not configured
@@ -333,8 +325,8 @@ drag = $special.drag = {
333 325
 		obj.originalX = ia.offset.left;
334 326
 		obj.originalY = ia.offset.top;
335 327
 		// adjusted element position
336  
-		obj.offsetX = event.pageX - ( dd.pageX - obj.originalX );
337  
-		obj.offsetY = event.pageY - ( dd.pageY - obj.originalY );
  328
+		obj.offsetX = obj.originalX + obj.deltaX; 
  329
+		obj.offsetY = obj.originalY + obj.deltaY;
338 330
 		// assign the drop targets information
339 331
 		obj.drop = drag.flatten( ( ia.drop || [] ).slice() );
340 332
 		obj.available = drag.flatten( ( ia.droppable || [] ).slice() );
@@ -382,6 +374,16 @@ drag.callback.prototype = {
382 374
 	}
383 375
 };
384 376
 
  377
+// patch $.event.handle to allow suppressing clicks
  378
+var orighandle = $event.handle;
  379
+$event.handle = function( event ){
  380
+	if ( $.data( this, "suppress."+ event.type ) - new Date().getTime() > 0 ){
  381
+		$.removeData( this, "suppress."+ event.type );
  382
+		return;
  383
+	}
  384
+	return orighandle.apply( this, arguments );
  385
+};
  386
+
385 387
 // share the same special event configuration with related events...
386 388
 $special.draginit = $special.dragstart = $special.dragend = drag;
387 389
 

0 notes on commit b0bafd0

Please sign in to comment.
Something went wrong with that request. Please try again.