primo commit
This commit is contained in:
		| @ -0,0 +1,206 @@ | ||||
| /*! Overthrow. An overflow:auto polyfill for responsive design. (c) 2012: Scott Jehl, Filament Group, Inc. http://filamentgroup.github.com/Overthrow/license.txt */ | ||||
| (function( w, o, undefined ){ | ||||
|  | ||||
| 	// o is overthrow reference from overthrow-polyfill.js | ||||
| 	if( o === undefined ){ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	o.scrollIndicatorClassName = "overthrow"; | ||||
| 	 | ||||
| 	var doc = w.document, | ||||
| 		docElem = doc.documentElement, | ||||
| 		// o api | ||||
| 		nativeOverflow = o.support === "native", | ||||
| 		canBeFilledWithPoly = o.canBeFilledWithPoly, | ||||
| 		configure = o.configure, | ||||
| 		set = o.set, | ||||
| 		forget = o.forget, | ||||
| 		scrollIndicatorClassName = o.scrollIndicatorClassName; | ||||
|  | ||||
| 	// find closest overthrow (elem or a parent) | ||||
| 	o.closest = function( target, ascend ){ | ||||
| 		return !ascend && target.className && target.className.indexOf( scrollIndicatorClassName ) > -1 && target || o.closest( target.parentNode ); | ||||
| 	}; | ||||
| 		 | ||||
| 	// polyfill overflow | ||||
| 	var enabled = false; | ||||
| 	o.set = function(){ | ||||
| 			 | ||||
| 		set(); | ||||
|  | ||||
| 		// If nativeOverflow or it doesn't look like the browser canBeFilledWithPoly, our job is done here. Exit viewport left. | ||||
| 		if( enabled || nativeOverflow || !canBeFilledWithPoly ){ | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		w.overthrow.addClass(); | ||||
|  | ||||
| 		enabled = true; | ||||
|  | ||||
| 		o.support = "polyfilled"; | ||||
|  | ||||
| 		o.forget = function(){ | ||||
| 			forget(); | ||||
| 			enabled = false; | ||||
| 			// Remove touch binding (check for method support since this part isn't qualified by touch support like the rest) | ||||
| 			if( doc.removeEventListener ){ | ||||
| 				doc.removeEventListener( "touchstart", start, false ); | ||||
| 			} | ||||
| 		}; | ||||
|  | ||||
| 		// Fill 'er up! | ||||
| 		// From here down, all logic is associated with touch scroll handling | ||||
| 			// elem references the overthrow element in use | ||||
| 		var elem, | ||||
| 			 | ||||
| 			// The last several Y values are kept here | ||||
| 			lastTops = [], | ||||
| 	 | ||||
| 			// The last several X values are kept here | ||||
| 			lastLefts = [], | ||||
| 			 | ||||
| 			// lastDown will be true if the last scroll direction was down, false if it was up | ||||
| 			lastDown, | ||||
| 			 | ||||
| 			// lastRight will be true if the last scroll direction was right, false if it was left | ||||
| 			lastRight, | ||||
| 			 | ||||
| 			// For a new gesture, or change in direction, reset the values from last scroll | ||||
| 			resetVertTracking = function(){ | ||||
| 				lastTops = []; | ||||
| 				lastDown = null; | ||||
| 			}, | ||||
| 			 | ||||
| 			resetHorTracking = function(){ | ||||
| 				lastLefts = []; | ||||
| 				lastRight = null; | ||||
| 			}, | ||||
| 		 | ||||
| 			// On webkit, touch events hardly trickle through textareas and inputs | ||||
| 			// Disabling CSS pointer events makes sure they do, but it also makes the controls innaccessible | ||||
| 			// Toggling pointer events at the right moments seems to do the trick | ||||
| 			// Thanks Thomas Bachem http://stackoverflow.com/a/5798681 for the following | ||||
| 			inputs, | ||||
| 			setPointers = function( val ){ | ||||
| 				inputs = elem.querySelectorAll( "textarea, input" ); | ||||
| 				for( var i = 0, il = inputs.length; i < il; i++ ) { | ||||
| 					inputs[ i ].style.pointerEvents = val; | ||||
| 				} | ||||
| 			}, | ||||
| 			 | ||||
| 			// For nested overthrows, changeScrollTarget restarts a touch event cycle on a parent or child overthrow | ||||
| 			changeScrollTarget = function( startEvent, ascend ){ | ||||
| 				if( doc.createEvent ){ | ||||
| 					var newTarget = ( !ascend || ascend === undefined ) && elem.parentNode || elem.touchchild || elem, | ||||
| 						tEnd; | ||||
| 							 | ||||
| 					if( newTarget !== elem ){ | ||||
| 						tEnd = doc.createEvent( "HTMLEvents" ); | ||||
| 						tEnd.initEvent( "touchend", true, true ); | ||||
| 						elem.dispatchEvent( tEnd ); | ||||
| 						newTarget.touchchild = elem; | ||||
| 						elem = newTarget; | ||||
| 						newTarget.dispatchEvent( startEvent ); | ||||
| 					} | ||||
| 				} | ||||
| 			}, | ||||
| 			 | ||||
| 			// Touchstart handler | ||||
| 			// On touchstart, touchmove and touchend are freshly bound, and all three share a bunch of vars set by touchstart | ||||
| 			// Touchend unbinds them again, until next time | ||||
| 			start = function( e ){ | ||||
|  | ||||
| 				// Stop any throw in progress | ||||
| 				if( o.intercept ){ | ||||
| 					o.intercept(); | ||||
| 				} | ||||
| 				 | ||||
| 				// Reset the distance and direction tracking | ||||
| 				resetVertTracking(); | ||||
| 				resetHorTracking(); | ||||
| 				 | ||||
| 				elem = o.closest( e.target ); | ||||
| 					 | ||||
| 				if( !elem || elem === docElem || e.touches.length > 1 ){ | ||||
| 					return; | ||||
| 				}			 | ||||
|  | ||||
| 				setPointers( "none" ); | ||||
| 				var touchStartE = e, | ||||
| 					scrollT = elem.scrollTop, | ||||
| 					scrollL = elem.scrollLeft, | ||||
| 					height = elem.offsetHeight, | ||||
| 					width = elem.offsetWidth, | ||||
| 					startY = e.touches[ 0 ].pageY, | ||||
| 					startX = e.touches[ 0 ].pageX, | ||||
| 					scrollHeight = elem.scrollHeight, | ||||
| 					scrollWidth = elem.scrollWidth, | ||||
| 				 | ||||
| 					// Touchmove handler | ||||
| 					move = function( e ){ | ||||
| 					 | ||||
| 						var ty = scrollT + startY - e.touches[ 0 ].pageY, | ||||
| 							tx = scrollL + startX - e.touches[ 0 ].pageX, | ||||
| 							down = ty >= ( lastTops.length ? lastTops[ 0 ] : 0 ), | ||||
| 							right = tx >= ( lastLefts.length ? lastLefts[ 0 ] : 0 ); | ||||
| 							 | ||||
| 						// If there's room to scroll the current container, prevent the default window scroll | ||||
| 						if( ( ty > 0 && ty < scrollHeight - height ) || ( tx > 0 && tx < scrollWidth - width ) ){ | ||||
| 							e.preventDefault(); | ||||
| 						} | ||||
| 						// This bubbling is dumb. Needs a rethink. | ||||
| 						else { | ||||
| 							changeScrollTarget( touchStartE ); | ||||
| 						} | ||||
| 						 | ||||
| 						// If down and lastDown are inequal, the y scroll has changed direction. Reset tracking. | ||||
| 						if( lastDown && down !== lastDown ){ | ||||
| 							resetVertTracking(); | ||||
| 						} | ||||
| 						 | ||||
| 						// If right and lastRight are inequal, the x scroll has changed direction. Reset tracking. | ||||
| 						if( lastRight && right !== lastRight ){ | ||||
| 							resetHorTracking(); | ||||
| 						} | ||||
| 						 | ||||
| 						// remember the last direction in which we were headed | ||||
| 						lastDown = down; | ||||
| 						lastRight = right;							 | ||||
| 						 | ||||
| 						// set the container's scroll | ||||
| 						elem.scrollTop = ty; | ||||
| 						elem.scrollLeft = tx; | ||||
| 					 | ||||
| 						lastTops.unshift( ty ); | ||||
| 						lastLefts.unshift( tx ); | ||||
| 					 | ||||
| 						if( lastTops.length > 3 ){ | ||||
| 							lastTops.pop(); | ||||
| 						} | ||||
| 						if( lastLefts.length > 3 ){ | ||||
| 							lastLefts.pop(); | ||||
| 						} | ||||
| 					}, | ||||
| 				 | ||||
| 					// Touchend handler | ||||
| 					end = function( e ){ | ||||
|  | ||||
| 						// Bring the pointers back | ||||
| 						setPointers( "auto" ); | ||||
| 						setTimeout( function(){ | ||||
| 							setPointers( "none" ); | ||||
| 						}, 450 ); | ||||
| 						elem.removeEventListener( "touchmove", move, false ); | ||||
| 						elem.removeEventListener( "touchend", end, false ); | ||||
| 					}; | ||||
| 				 | ||||
| 				elem.addEventListener( "touchmove", move, false ); | ||||
| 				elem.addEventListener( "touchend", end, false ); | ||||
| 			}; | ||||
| 			 | ||||
| 		// Bind to touch, handle move and end within | ||||
| 		doc.addEventListener( "touchstart", start, false ); | ||||
| 	}; | ||||
| 		 | ||||
| })( this, this.overthrow ); | ||||
		Reference in New Issue
	
	Block a user