1/* 2* @fileOverview TouchSwipe - jQuery Plugin 3* @version 1.6.6 4* 5* @author Matt Bryson http://www.github.com/mattbryson 6* @see https://github.com/mattbryson/TouchSwipe-Jquery-Plugin 7* @see http://labs.rampinteractive.co.uk/touchSwipe/ 8* @see http://plugins.jquery.com/project/touchSwipe 9* 10* Copyright (c) 2010-2015 Matt Bryson 11* Dual licensed under the MIT or GPL Version 2 licenses. 12* 13*/ 14 15/* 16* 17* Changelog 18* $Date: 2010-12-12 (Wed, 12 Dec 2010) $ 19* $version: 1.0.0 20* $version: 1.0.1 - removed multibyte comments 21* 22* $Date: 2011-21-02 (Mon, 21 Feb 2011) $ 23* $version: 1.1.0 - added allowPageScroll property to allow swiping and scrolling of page 24* - changed handler signatures so one handler can be used for multiple events 25* $Date: 2011-23-02 (Wed, 23 Feb 2011) $ 26* $version: 1.2.0 - added click handler. This is fired if the user simply clicks and does not swipe. The event object and click target are passed to handler. 27* - If you use the http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ plugin, you can also assign jQuery mouse events to children of a touchSwipe object. 28* $version: 1.2.1 - removed console log! 29* 30* $version: 1.2.2 - Fixed bug where scope was not preserved in callback methods. 31* 32* $Date: 2011-28-04 (Thurs, 28 April 2011) $ 33* $version: 1.2.4 - Changed licence terms to be MIT or GPL inline with jQuery. Added check for support of touch events to stop non compatible browsers erroring. 34* 35* $Date: 2011-27-09 (Tues, 27 September 2011) $
36* $version: 1.2.5 - Added support for testing swipes with mouse on desktop browser (thanks to https://github.com/joelhy) 37* 38* $Date: 2012-14-05 (Mon, 14 May 2012) $ 39* $version: 1.2.6 - Added timeThreshold between start and end touch, so user can ignore slow swipes (thanks to Mark Chase). Default is null, all swipes are detected 40* 41* $Date: 2012-05-06 (Tues, 05 June 2012) $ 42* $version: 1.2.7 - Changed time threshold to have null default for backwards compatibility. Added duration param passed back in events, and refactored how time is handled. 43* 44* $Date: 2012-05-06 (Tues, 05 June 2012) $ 45* $version: 1.2.8 - Added the possibility to return a value like null or false in the trigger callback. In that way we can control when the touch start/move should take effect or not (simply by returning in some cases return null; or return false;) This effects the ontouchstart/ontouchmove event. 46* 47* $Date: 2012-06-06 (Wed, 06 June 2012) $ 48* $version: 1.3.0 - Refactored whole plugin to allow for methods to be executed, as well as exposed defaults for user override. Added 'enable', 'disable', and 'destroy' methods 49* 50* $Date: 2012-05-06 (Fri, 05 June 2012) $ 51* $version: 1.3.1 - Bug fixes - bind() with false as last argument is no longer supported in jQuery 1.6, also, if you just click, the duration is now returned correctly. 52* 53* $Date: 2012-29-07 (Sun, 29 July 2012) $ 54* $version: 1.3.2 - Added fallbackToMouseEvents option to NOT capture mouse events on non touch devices. 55* - Added "all" fingers value to the fingers property, so any combination of fingers triggers the swipe, allowing event handlers to check the finger count 56* 57* $Date: 2012-09-08 (Thurs, 9 Aug 2012) $ 58* $version: 1.3.3 - Code tidy prep for minefied version 59* 60* $Date: 2012-04-10 (wed, 4 Oct 2012) $ 61* $version: 1.4.0 - Added pinch support, pinchIn and pinchOut 62* 63* $Date: 2012-11-10 (Thurs, 11 Oct 2012) $ 64* $version: 1.5.0 - Added excludedElements, a jquery selector that specifies child elements that do NOT trigger swipes. By default, this is one select that removes all form, input select, button and anchor elements. 65* 66* $Date: 2012-22-10 (Mon, 22 Oct 2012) $ 67* $version: 1.5.1 - Fixed bug with jQuery 1.8 and trailing comma in excludedElements 68* - Fixed bug with IE and eventPreventDefault() 69* $Date: 2013-01-12 (Fri, 12 Jan 2013) $ 70* $version: 1.6.0 - Fixed bugs with pinching, mainly when both pinch and swipe enabled, as well as adding time threshold for multifinger gestures, so releasing one finger beofre the other doesnt trigger as single finger gesture. 71* - made the demo site all static local HTML pages so they can be run locally by a developer 72* - added jsDoc comments and added documentation for the plugin 73* - code tidy 74* - added triggerOnTouchLeave property that will end the event when the user swipes off the element. 75* $Date: 2013-03-23 (Sat, 23 Mar 2013) $
76* $version: 1.6.1 - Added support for ie8 touch events 77* $version: 1.6.2 - Added support for events binding with on / off / bind in jQ for all callback names. 78* - Deprecated the 'click' handler in favour of tap. 79* - added cancelThreshold property 80* - added option method to update init options at runtime 81* $version 1.6.3 - added doubletap, longtap events and longTapThreshold, doubleTapThreshold property 82* 83* $Date: 2013-04-04 (Thurs, 04 April 2013) $ 84* $version 1.6.4 - Fixed bug with cancelThreshold introduced in 1.6.3, where swipe status no longer fired start event, and stopped once swiping back. 85* 86* $Date: 2013-08-24 (Sat, 24 Aug 2013) $ 87* $version 1.6.5 - Merged a few pull requests fixing various bugs, added AMD support. 88* 89* $Date: 2014-06-04 (Wed, 04 June 2014) $ 90* $version 1.6.6 - Merge of pull requests. 91* - IE10 touch support 92* - Only prevent default event handling on valid swipe 93* - Separate license/changelog comment 94* - Detect if the swipe is valid at the end of the touch event. 95* - Pass fingerdata to event handlers. 96* - Add 'hold' gesture 97* - Be more tolerant about the tap distance 98* - Typos and minor fixes 99* 100* $Date: 2015-22-01 (Thurs, 22 Jan 2015) $ 101* $version 1.6.7 - Added patch from https://github.com/mattbryson/TouchSwipe-Jquery-Plugin/issues/206 to fix memory leak 102* 103* $Date: 2015-2-2 (Mon, 2 Feb 2015) $ 104* $version 1.6.7 - Added preventDefaultEvents option to proxy events regardless. 105* - Fixed issue with swipe and pinch not triggering at the same time 106*/ 107 108/** 109 * See (http://jquery.com/). 110 * @name $ 111 * @class 112 * See the jQuery Library (http://jquery.com/) for full details. This just 113 * documents the function and classes that are added to jQuery by this plug-in. 114 */ 115 116/** 117 * See (http://jquery.com/) 118 * @name fn 119 * @class 120 * See the jQuery Library (http://jquery.com/) for full details. This just 121 * documents the function and classes that are added to jQuery by this plug-in. 122 * @memberOf $ 123 */ 124 125 126 127(function (factory) { 128 if (typeof define === 'function' && define.amd && define.amd.jQuery) { 129 // AMD. Register as anonymous module. 130 define(['jquery'], factory); 131 } else { 132 // Browser globals. 133 factory(jQuery); 134 } 135}(function ($) { 136 "use strict"; 137 138 //Constants 139 var LEFT = "left", 140 RIGHT = "right", 141 UP = "up", 142 DOWN = "down", 143 IN = "in", 144 OUT = "out", 145 146 NONE = "none", 147 AUTO = "auto", 148 149 SWIPE = "swipe", 150 PINCH = "pinch", 151 TAP = "tap", 152 DOUBLE_TAP = "doubletap", 153 LONG_TAP = "longtap", 154 HOLD = "hold", 155 156 HORIZONTAL = "horizontal", 157 VERTICAL = "vertical", 158 159 ALL_FINGERS = "all", 160 161 DOUBLE_TAP_THRESHOLD = 10, 162 163 PHASE_START = "start", 164 PHASE_MOVE = "move", 165 PHASE_END = "end", 166 PHASE_CANCEL = "cancel", 167 168 SUPPORTS_TOUCH = 'ontouchstart' in window, 169 170 SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.navigator.pointerEnabled, 171 172 SUPPORTS_POINTER = window.navigator.pointerEnabled || window.navigator.msPointerEnabled, 173 174 PLUGIN_NS = 'TouchSwipe'; 175 176 177 178 /** 179 * The default configuration, and available options to configure touch swipe with. 180 * You can set the default values by updating any of the properties prior to instantiation. 181 * @name $.fn.swipe.defaults 182 * @namespace 183 * @property {int} [fingers=1] The number of fingers to detect in a swipe. Any swipes that do not meet this requirement will NOT trigger swipe handlers. 184 * @property {int} [threshold=75] The number of pixels that the user must move their finger by before it is considered a swipe. 185 * @property {int} [cancelThreshold=null] The number of pixels that the user must move their finger back from the original swipe direction to cancel the gesture. 186 * @property {int} [pinchThreshold=20] The number of pixels that the user must pinch their finger by before it is considered a pinch. 187 * @property {int} [maxTimeThreshold=null] Time, in milliseconds, between touchStart and touchEnd must NOT exceed in order to be considered a swipe. 188 * @property {int} [fingerReleaseThreshold=250] Time in milliseconds between releasing multiple fingers. If 2 fingers are down, and are released one after the other, if they are within this threshold, it counts as a simultaneous release. 189 * @property {int} [longTapThreshold=500] Time in milliseconds between tap and release for a long tap 190 * @property {int} [doubleTapThreshold=200] Time in milliseconds between 2 taps to count as a double tap 191 * @property {function} [swipe=null] A handler to catch all swipes. See {@link $.fn.swipe#event:swipe} 192 * @property {function} [swipeLeft=null] A handler that is triggered for "left" swipes. See {@link $.fn.swipe#event:swipeLeft} 193 * @property {function} [swipeRight=null] A handler that is triggered for "right" swipes. See {@link $.fn.swipe#event:swipeRight} 194 * @property {function} [swipeUp=null] A handler that is triggered for "up" swipes. See {@link $.fn.swipe#event:swipeUp} 195 * @property {function} [swipeDown=null] A handler that is triggered for "down" swipes. See {@link $.fn.swipe#event:swipeDown} 196 * @property {function} [swipeStatus=null] A handler triggered for every phase of the swipe. See {@link $.fn.swipe#event:swipeStatus} 197 * @property {function} [pinchIn=null] A handler triggered for pinch in events. See {@link $.fn.swipe#event:pinchIn} 198 * @property {function} [pinchOut=null] A handler triggered for pinch out events. See {@link $.fn.swipe#event:pinchOut} 199 * @property {function} [pinchStatus=null] A handler triggered for every phase of a pinch. See {@link $.fn.swipe#event:pinchStatus} 200 * @property {function} [tap=null] A handler triggered when a user just taps on the item, rather than swipes it. If they do not move, tap is triggered, if they do move, it is not. 201 * @property {function} [doubleTap=null] A handler triggered when a user double taps on the item. The delay between taps can be set with the doubleTapThreshold property. See {@link $.fn.swipe.defaults#doubleTapThreshold} 202 * @property {function} [longTap=null] A handler triggered when a user long taps on the item. The delay between start and end can be set with the longTapThreshold property. See {@link $.fn.swipe.defaults#longTapThreshold} 203 * @property (function) [hold=null] A handler triggered when a user reaches longTapThreshold on the item. See {@link $.fn.swipe.defaults#longTapThreshold} 204 * @property {boolean} [triggerOnTouchEnd=true] If true, the swipe events are triggered when the touch end event is received (user releases finger). If false, it will be triggered on reaching the threshold, and then cancel the touch event automatically. 205 * @property {boolean} [triggerOnTouchLeave=false] If true, then when the user leaves the swipe object, the swipe will end and trigger appropriate handlers. 206 * @property {string|undefined} [allowPageScroll='auto'] How the browser handles page scrolls when the user is swiping on a touchSwipe object. See {@link $.fn.swipe.pageScroll}. <br/><br/> 207 <code>"auto"</code> : all undefined swipes will cause the page to scroll in that direction. <br/> 208 <code>"none"</code> : the page will not scroll when user swipes. <br/> 209 <code>"horizontal"</code> : will force page to scroll on horizontal swipes. <br/> 210 <code>"vertical"</code> : will force page to scroll on vertical swipes. <br/> 211 * @property {boolean} [fallbackToMouseEvents=true] If true mouse events are used when run on a non touch device, false will stop swipes being triggered by mouse events on non tocuh devices. 212 * @property {string} [excludedElements="button, input, select, textarea, a, .noSwipe"] A jquery selector that specifies child elements that do NOT trigger swipes. By default this excludes all form, input, select, button, anchor and .noSwipe elements. 213 * @property {boolean} [preventDefaultEvents=true] by default default events are cancelled, so the page doesn't move. You can dissable this so both native events fire as well as your handlers. 214 215 */ 216 var defaults = { 217 fingers: 1, 218 threshold: 75, 219 cancelThreshold:null, 220 pinchThreshold:20, 221 maxTimeThreshold: null, 222 fingerReleaseThreshold:250, 223 longTapThreshold:500, 224 doubleTapThreshold:200, 225 swipe: null, 226 swipeLeft: null, 227 swipeRight: null, 228 swipeUp: null, 229 swipeDown: null, 230 swipeStatus: null, 231 pinchIn:null, 232 pinchOut:null, 233 pinchStatus:null, 234 click:null, //Deprecated since 1.6.2 235 tap:null, 236 doubleTap:null, 237 longTap:null, 238 hold:null, 239 triggerOnTouchEnd: true, 240 triggerOnTouchLeave:false, 241 allowPageScroll: "auto", 242 fallbackToMouseEvents: false, 243 excludedElements:"label, button, input, select, textarea, a, .noSwipe, video", 244 preventDefaultEvents:true 245 }; 246 247 248 249 /** 250 * Applies TouchSwipe behaviour to one or more jQuery objects. 251 * The TouchSwipe plugin can be instantiated via this method, or methods within
252 * TouchSwipe can be executed via this method as per jQuery plugin architecture. 253 * @see TouchSwipe 254 * @class 255 * @param {Mixed} method If the current DOMNode is a TouchSwipe object, and <code>method</code> is a TouchSwipe method, then 256 * the <code>method</code> is executed, and any following arguments are passed to the TouchSwipe method. 257 * If <code>method</code> is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the 258 * configuration properties defined in the object. See TouchSwipe 259 * 260 */ 261 $.fn.swipe = function (method) { 262 var $this = $(this), 263 plugin = $this.data(PLUGIN_NS); 264 265 //Check if we are already instantiated and trying to execute a method 266 if (plugin && typeof method === 'string') { 267 if (plugin[method]) { 268 return plugin[method].apply(this, Array.prototype.slice.call(arguments, 1)); 269 } else { 270 $.error('Method ' + method + ' does not exist on jQuery.swipe'); 271 } 272 } 273 //Else not instantiated and trying to pass init object (or nothing) 274 else if (!plugin && (typeof method === 'object' || !method)) { 275 return init.apply(this, arguments); 276 } 277 278 return $this; 279 }; 280 281 //Expose our defaults so a user could override the plugin defaults 282 $.fn.swipe.defaults = defaults; 283 284 /** 285 * The phases that a touch event goes through. The <code>phase</code> is passed to the event handlers. 286 * These properties are read only, attempting to change them will not alter the values passed to the event handlers. 287 * @namespace 288 * @readonly 289 * @property {string} PHASE_START Constant indicating the start phase of the touch event. Value is <code>"start"</code>. 290 * @property {string} PHASE_MOVE Constant indicating the move phase of the touch event. Value is <code>"move"</code>. 291 * @property {string} PHASE_END Constant indicating the end phase of the touch event. Value is <code>"end"</code>. 292 * @property {string} PHASE_CANCEL Constant indicating the cancel phase of the touch event. Value is <code>"cancel"</code>. 293 */ 294 $.fn.swipe.phases = { 295 PHASE_START: PHASE_START, 296 PHASE_MOVE: PHASE_MOVE, 297 PHASE_END: PHASE_END, 298 PHASE_CANCEL: PHASE_CANCEL 299 }; 300 301 /** 302 * The direction constants that are passed to the event handlers. 303 * These properties are read only, attempting to change them will not alter the values passed to the event handlers. 304 * @namespace 305 * @readonly 306 * @property {string} LEFT Constant indicating the left direction. Value is <code>"left"</code>. 307 * @property {string} RIGHT Constant indicating the right direction. Value is <code>"right"</code>. 308 * @property {string} UP Constant indicating the up direction. Value is <code>"up"</code>. 309 * @property {string} DOWN Constant indicating the down direction. Value is <code>"cancel"</code>. 310 * @property {string} IN Constant indicating the in direction. Value is <code>"in"</code>. 311 * @property {string} OUT Constant indicating the out direction. Value is <code>"out"</code>. 312 */ 313 $.fn.swipe.directions = { 314 LEFT: LEFT, 315 RIGHT: RIGHT, 316 UP: UP, 317 DOWN: DOWN, 318 IN : IN, 319 OUT: OUT 320 }; 321 322 /** 323 * The page scroll constants that can be used to set the value of <code>allowPageScroll</code> option 324 * These properties are read only 325 * @namespace 326 * @readonly 327 * @see $.fn.swipe.defaults#allowPageScroll 328 * @property {string} NONE Constant indicating no page scrolling is allowed. Value is <code>"none"</code>. 329 * @property {string} HORIZONTAL Constant indicating horizontal page scrolling is allowed. Value is <code>"horizontal"</code>. 330 * @property {string} VERTICAL Constant indicating vertical page scrolling is allowed. Value is <code>"vertical"</code>. 331 * @property {string} AUTO Constant indicating either horizontal or vertical will be allowed, depending on the swipe handlers registered. Value is <code>"auto"</code>. 332 */ 333 $.fn.swipe.pageScroll = { 334 NONE: NONE, 335 HORIZONTAL: HORIZONTAL, 336 VERTICAL: VERTICAL, 337 AUTO: AUTO 338 }; 339 340 /** 341 * Constants representing the number of fingers used in a swipe. These are used to set both the value of <code>fingers</code> in the 342 * options object, as well as the value of the <code>fingers</code> event property. 343 * These properties are read only, attempting to change them will not alter the values passed to the event handlers. 344 * @namespace 345 * @readonly 346 * @see $.fn.swipe.defaults#fingers 347 * @property {string} ONE Constant indicating 1 finger is to be detected / was detected. Value is <code>1</code>. 348 * @property {string} TWO Constant indicating 2 fingers are to be detected / were detected. Value is <code>1</code>. 349 * @property {string} THREE Constant indicating 3 finger are to be detected / were detected. Value is <code>1</code>. 350 * @property {string} ALL Constant indicating any combination of finger are to be detected. Value is <code>"all"</code>. 351 */ 352 $.fn.swipe.fingers = { 353 ONE: 1, 354 TWO: 2, 355 THREE: 3, 356 ALL: ALL_FINGERS 357 }; 358 359 /** 360 * Initialise the plugin for each DOM element matched
361 * This creates a new instance of the main TouchSwipe class for each DOM element, and then 362 * saves a reference to that instance in the elements data property. 363 * @internal 364 */ 365 function init(options) { 366 //Prep and extend the options 367 if (options && (options.allowPageScroll === undefined && (options.swipe !== undefined || options.swipeStatus !== undefined))) { 368 options.allowPageScroll = NONE; 369 } 370 371 //Check for deprecated options 372 //Ensure that any old click handlers are assigned to the new tap, unless we have a tap 373 if(options.click!==undefined && options.tap===undefined) { 374 options.tap = options.click; 375 } 376 377 if (!options) { 378 options = {}; 379 } 380 381 //pass empty object so we dont modify the defaults 382 options = $.extend({}, $.fn.swipe.defaults, options); 383 384 //For each element instantiate the plugin 385 return this.each(function () { 386 var $this = $(this); 387 388 //Check we havent already initialised the plugin 389 var plugin = $this.data(PLUGIN_NS); 390 391 if (!plugin) { 392 plugin = new TouchSwipe(this, options); 393 $this.data(PLUGIN_NS, plugin); 394 } 395 }); 396 } 397 398 /** 399 * Main TouchSwipe Plugin Class. 400 * Do not use this to construct your TouchSwipe object, use the jQuery plugin method $.fn.swipe(); {@link $.fn.swipe} 401 * @private 402 * @name TouchSwipe 403 * @param {DOMNode} element The HTML DOM object to apply to plugin to 404 * @param {Object} options The options to configure the plugin with. @link {$.fn.swipe.defaults} 405 * @see $.fh.swipe.defaults 406 * @see $.fh.swipe 407 * @class 408 */ 409 function TouchSwipe(element, options) { 410 var useTouchEvents = (SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents), 411 START_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerDown' : 'pointerdown') : 'touchstart') : 'mousedown', 412 MOVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerMove' : 'pointermove') : 'touchmove') : 'mousemove', 413 END_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerUp' : 'pointerup') : 'touchend') : 'mouseup', 414 LEAVE_EV = useTouchEvents ? null : 'mouseleave', //we manually detect leave on touch devices, so null event here 415 CANCEL_EV = (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerCancel' : 'pointercancel') : 'touchcancel'); 416 417 418 419 //touch properties 420 var distance = 0, 421 direction = null, 422 duration = 0, 423 startTouchesDistance = 0, 424 endTouchesDistance = 0, 425 pinchZoom = 1, 426 pinchDistance = 0, 427 pinchDirection = 0, 428 maximumsMap=null; 429 430 431 432 //jQuery wrapped element for this instance 433 var $element = $(element); 434 435 //Current phase of th touch cycle 436 var phase = "start"; 437 438 // the current number of fingers being used. 439 var fingerCount = 0; 440 441 //track mouse points / delta 442 var fingerData=null; 443 444 //track times 445 var startTime = 0, 446 endTime = 0, 447 previousTouchEndTime=0, 448 previousTouchFingerCount=0, 449 doubleTapStartTime=0; 450 451 //Timeouts 452 var singleTapTimeout=null, 453 holdTimeout=null; 454 455 // Add gestures to all swipable areas if supported 456 try { 457 $element.bind(START_EV, touchStart); 458 $element.bind(CANCEL_EV, touchCancel); 459 } 460 catch (e) { 461 $.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe'); 462 } 463 464 // 465 //Public methods 466 // 467 468 /** 469 * re-enables the swipe plugin with the previous configuration 470 * @function 471 * @name $.fn.swipe#enable 472 * @return {DOMNode} The Dom element that was registered with TouchSwipe 473 * @example $("#element").swipe("enable"); 474 */ 475 this.enable = function () { 476 $element.bind(START_EV, touchStart); 477 $element.bind(CANCEL_EV, touchCancel); 478 return $element; 479 }; 480 481 /** 482 * disables the swipe plugin 483 * @function 484 * @name $.fn.swipe#disable 485 * @return {DOMNode} The Dom element that is now registered with TouchSwipe 486 * @example $("#element").swipe("disable"); 487 */ 488 this.disable = function () { 489 removeListeners(); 490 return $element; 491 }; 492 493 /** 494 * Destroy the swipe plugin completely. To use any swipe methods, you must re initialise the plugin. 495 * @function 496 * @name $.fn.swipe#destroy 497 * @example $("#element").swipe("destroy"); 498 */ 499 this.destroy = function () { 500 removeListeners(); 501 $element.data(PLUGIN_NS, null); 502 $element = null; 503 }; 504 505 506 /** 507 * Allows run time updating of the swipe configuration options. 508 * @function 509 * @name $.fn.swipe#option 510 * @param {String} property The option property to get or set 511 * @param {Object} [value] The value to set the property to 512 * @return {Object} If only a property name is passed, then that property value is returned. 513 * @example $("#element").swipe("option", "threshold"); // return the threshold 514 * @example $("#element").swipe("option", "threshold", 100); // set the threshold after init 515 * @see $.fn.swipe.defaults 516 * 517 */ 518 this.option = function (property, value) { 519 if(options[property]!==undefined) { 520 if(value===undefined) { 521 return options[property]; 522 } else { 523 options[property] = value; 524 } 525 } else { 526 $.error('Option ' + property + ' does not exist on jQuery.swipe.options'); 527 } 528 529 return null; 530 } 531 532 // 533 // Private methods 534 // 535 536 // 537 // EVENTS 538 // 539 /** 540 * Event handler for a touch start event. 541 * Stops the default click event from triggering and stores where we touched 542 * @inner 543 * @param {object} jqEvent The normalised jQuery event object. 544 */ 545 function touchStart(jqEvent) { 546 //If we already in a touch event (a finger already in use) then ignore subsequent ones.. 547 if( getTouchInProgress() ) 548 return; 549 550 //Check if this element matches any in the excluded elements selectors, or its parent is excluded, if so, DON'T swipe 551 if( $(jqEvent.target).closest( options.excludedElements, $element ).length>0 ) 552 return; 553 554 //As we use Jquery bind for events, we need to target the original event object 555 //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one. 556 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 557 558 var ret, 559 evt = SUPPORTS_TOUCH ? event.touches[0] : event; 560 561 phase = PHASE_START; 562 563 //If we support touches, get the finger count 564 if (SUPPORTS_TOUCH) { 565 // get the total number of fingers touching the screen 566 fingerCount = event.touches.length; 567 } 568 //Else this is the desktop, so stop the browser from dragging content 569 else { 570 jqEvent.preventDefault(); //call this on jq event so we are cross browser 571 } 572 573 //clear vars.. 574 distance = 0; 575 direction = null; 576 pinchDirection=null; 577 duration = 0; 578 startTouchesDistance=0; 579 endTouchesDistance=0; 580 pinchZoom = 1; 581 pinchDistance = 0; 582 fingerData=createAllFingerData(); 583 maximumsMap=createMaximumsData(); 584 cancelMultiFingerRelease(); 585 586 587 // check the number of fingers is what we are looking for, or we are capturing pinches 588 if (!SUPPORTS_TOUCH || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) { 589 // get the coordinates of the touch 590 createFingerData( 0, evt ); 591 startTime = getTimeStamp(); 592 593 if(fingerCount==2) { 594 //Keep track of the initial pinch distance, so we can calculate the diff later 595 //Store second finger data as start 596 createFingerData( 1, event.touches[1] ); 597 startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start); 598 } 599 600 if (options.swipeStatus || options.pinchStatus) { 601 ret = triggerHandler(event, phase); 602 } 603 } 604 else { 605 //A touch with more or less than the fingers we are looking for, so cancel 606 ret = false; 607 } 608 609 //If we have a return value from the users handler, then return and cancel 610 if (ret === false) { 611 phase = PHASE_CANCEL; 612 triggerHandler(event, phase); 613 return ret; 614 } 615 else { 616 if (options.hold) { 617 holdTimeout = setTimeout($.proxy(function() { 618 //Trigger the event 619 $element.trigger('hold', [event.target]); 620 //Fire the callback 621 if(options.hold) { 622 ret = options.hold.call($element, event, event.target); 623 } 624 }, this), options.longTapThreshold ); 625 } 626 627 setTouchInProgress(true); 628 } 629 630 return null; 631 }; 632
vendor: 7,941 bytes, lines 633-877
633 634 635 /** 636 * Event handler for a touch move event. 637 * If we change fingers during move, then cancel the event 638 * @inner 639 * @param {object} jqEvent The normalised jQuery event object. 640 */ 641 function touchMove(jqEvent) { 642 643 //As we use Jquery bind for events, we need to target the original event object 644 //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one. 645 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 646 647 //If we are ending, cancelling, or within the threshold of 2 fingers being released, don't track anything.. 648 if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease()) 649 return; 650 651 var ret, 652 evt = SUPPORTS_TOUCH ? event.touches[0] : event; 653 654 655 //Update the finger data 656 var currentFinger = updateFingerData(evt); 657 endTime = getTimeStamp(); 658 659 if (SUPPORTS_TOUCH) { 660 fingerCount = event.touches.length; 661 } 662 663 if (options.hold) 664 clearTimeout(holdTimeout); 665 666 phase = PHASE_MOVE; 667 668 //If we have 2 fingers get Touches distance as well 669 if(fingerCount==2) { 670 671 //Keep track of the initial pinch distance, so we can calculate the diff later 672 //We do this here as well as the start event, in case they start with 1 finger, and the press 2 fingers 673 if(startTouchesDistance==0) { 674 //Create second finger if this is the first time... 675 createFingerData( 1, event.touches[1] ); 676 677 startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start); 678 } else { 679 //Else just update the second finger 680 updateFingerData(event.touches[1]); 681 682 endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end); 683 pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end); 684 } 685 686 687 pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance); 688 pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance); 689 } 690 691 692 693 694 if ( (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH || hasPinches() ) { 695 696 direction = calculateDirection(currentFinger.start, currentFinger.end); 697 698 //Check if we need to prevent default event (page scroll / pinch zoom) or not 699 validateDefaultEvent(jqEvent, direction); 700 701 //Distance and duration are all off the main finger 702 distance = calculateDistance(currentFinger.start, currentFinger.end); 703 duration = calculateDuration(); 704 705 //Cache the maximum distance we made in this direction 706 setMaxDistance(direction, distance); 707 708 709 if (options.swipeStatus || options.pinchStatus) { 710 ret = triggerHandler(event, phase); 711 } 712 713 714 //If we trigger end events when threshold are met, or trigger events when touch leaves element 715 if(!options.triggerOnTouchEnd || options.triggerOnTouchLeave) { 716 717 var inBounds = true; 718 719 //If checking if we leave the element, run the bounds check (we can use touchleave as its not supported on webkit) 720 if(options.triggerOnTouchLeave) { 721 var bounds = getbounds( this ); 722 inBounds = isInBounds( currentFinger.end, bounds ); 723 } 724 725 //Trigger end handles as we swipe if thresholds met or if we have left the element if the user has asked to check these.. 726 if(!options.triggerOnTouchEnd && inBounds) { 727 phase = getNextPhase( PHASE_MOVE ); 728 } 729 //We end if out of bounds here, so set current phase to END, and check if its modified 730 else if(options.triggerOnTouchLeave && !inBounds ) { 731 phase = getNextPhase( PHASE_END ); 732 } 733 734 if(phase==PHASE_CANCEL || phase==PHASE_END) { 735 triggerHandler(event, phase); 736 } 737 } 738 } 739 else { 740 phase = PHASE_CANCEL; 741 triggerHandler(event, phase); 742 } 743 744 if (ret === false) { 745 phase = PHASE_CANCEL; 746 triggerHandler(event, phase); 747 } 748 } 749 750 751 752 /** 753 * Event handler for a touch end event. 754 * Calculate the direction and trigger events 755 * @inner 756 * @param {object} jqEvent The normalised jQuery event object. 757 */ 758 function touchEnd(jqEvent) { 759 //As we use Jquery bind for events, we need to target the original event object 760 var event = jqEvent.originalEvent; 761 762 763 //If we are still in a touch with another finger return 764 //This allows us to wait a fraction and see if the other finger comes up, if it does within the threshold, then we treat it as a multi release, not a single release. 765 if (SUPPORTS_TOUCH) { 766 if(event.touches.length>0) { 767 startMultiFingerRelease(); 768 return true; 769 } 770 } 771 772 //If a previous finger has been released, check how long ago, if within the threshold, then assume it was a multifinger release. 773 //This is used to allow 2 fingers to release fractionally after each other, whilst maintainig the event as containg 2 fingers, not 1 774 if(inMultiFingerRelease()) { 775 fingerCount=previousTouchFingerCount; 776 } 777 778 //Set end of swipe 779 endTime = getTimeStamp(); 780 781 //Get duration incase move was never fired 782 duration = calculateDuration(); 783 784 //If we trigger handlers at end of swipe OR, we trigger during, but they didnt trigger and we are still in the move phase 785 if(didSwipeBackToCancel() || !validateSwipeDistance()) { 786 phase = PHASE_CANCEL; 787 triggerHandler(event, phase); 788 } else if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd == false && phase === PHASE_MOVE)) { 789 //call this on jq event so we are cross browser 790 jqEvent.preventDefault(); 791 phase = PHASE_END; 792 triggerHandler(event, phase); 793 } 794 //Special cases - A tap should always fire on touch end regardless, 795 //So here we manually trigger the tap end handler by itself 796 //We dont run trigger handler as it will re-trigger events that may have fired already 797 else if (!options.triggerOnTouchEnd && hasTap()) { 798 //Trigger the pinch events... 799 phase = PHASE_END; 800 triggerHandlerForGesture(event, phase, TAP); 801 } 802 else if (phase === PHASE_MOVE) { 803 phase = PHASE_CANCEL; 804 triggerHandler(event, phase); 805 } 806 807 setTouchInProgress(false); 808 809 return null; 810 } 811 812 813 814 /** 815 * Event handler for a touch cancel event. 816 * Clears current vars 817 * @inner 818 */ 819 function touchCancel() { 820 // reset the variables back to default values 821 fingerCount = 0; 822 endTime = 0; 823 startTime = 0; 824 startTouchesDistance=0; 825 endTouchesDistance=0; 826 pinchZoom=1; 827 828 //If we were in progress of tracking a possible multi touch end, then re set it. 829 cancelMultiFingerRelease(); 830 831 setTouchInProgress(false); 832 } 833 834 835 /** 836 * Event handler for a touch leave event. 837 * This is only triggered on desktops, in touch we work this out manually 838 * as the touchleave event is not supported in webkit 839 * @inner 840 */ 841 function touchLeave(jqEvent) { 842 var event = jqEvent.originalEvent; 843 844 //If we have the trigger on leave property set.... 845 if(options.triggerOnTouchLeave) { 846 phase = getNextPhase( PHASE_END ); 847 triggerHandler(event, phase); 848 } 849 } 850 851 /** 852 * Removes all listeners that were associated with the plugin 853 * @inner 854 */ 855 function removeListeners() { 856 $element.unbind(START_EV, touchStart); 857 $element.unbind(CANCEL_EV, touchCancel); 858 $element.unbind(MOVE_EV, touchMove); 859 $element.unbind(END_EV, touchEnd); 860 861 //we only have leave events on desktop, we manually calculate leave on touch as its not supported in webkit 862 if(LEAVE_EV) { 863 $element.unbind(LEAVE_EV, touchLeave); 864 } 865 866 setTouchInProgress(false); 867 } 868 869 870 /** 871 * Checks if the time and distance thresholds have been met, and if so then the appropriate handlers are fired. 872 */ 873 function getNextPhase(currentPhase) { 874 875 var nextPhase = currentPhase; 876 877 // Ensure we have valid swipe (under time and over distance and check if we are out of bound...)
878 var validTime = validateSwipeTime(); 879 var validDistance = validateSwipeDistance(); 880 var didCancel = didSwipeBackToCancel(); 881 882 //If we have exceeded our time, then cancel 883 if(!validTime || didCancel) { 884 nextPhase = PHASE_CANCEL; 885 } 886 //Else if we are moving, and have reached distance then end 887 else if (validDistance && currentPhase == PHASE_MOVE && (!options.triggerOnTouchEnd || options.triggerOnTouchLeave) ) { 888 nextPhase = PHASE_END; 889 } 890 //Else if we have ended by leaving and didn't reach distance, then cancel 891 else if (!validDistance && currentPhase==PHASE_END && options.triggerOnTouchLeave) { 892 nextPhase = PHASE_CANCEL; 893 } 894 895 return nextPhase; 896 } 897 898 899 /** 900 * Trigger the relevant event handler 901 * The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down" 902 * @param {object} event the original event object 903 * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases} 904 * @inner 905 */ 906 function triggerHandler(event, phase) { 907 908 var ret = undefined; 909 910 //Swipes and pinches are not mutually exclusive - can happend at same time, so need to trigger 2 events potentially 911 if( (didSwipe() || hasSwipes()) || (didPinch() || hasPinches()) ) { 912 // SWIPE GESTURES 913 if(didSwipe() || hasSwipes()) { //hasSwipes as status needs to fire even if swipe is invalid 914 //Trigger the swipe events... 915 ret = triggerHandlerForGesture(event, phase, SWIPE); 916 } 917 918 // PINCH GESTURES (if the above didn't cancel) 919 if((didPinch() || hasPinches()) && ret!==false) { 920 //Trigger the pinch events... 921 ret = triggerHandlerForGesture(event, phase, PINCH); 922 } 923 } else { 924 925 // CLICK / TAP (if the above didn't cancel) 926 if(didDoubleTap() && ret!==false) { 927 //Trigger the tap events... 928 ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP); 929 } 930 931 // CLICK / TAP (if the above didn't cancel) 932 else if(didLongTap() && ret!==false) { 933 //Trigger the tap events... 934 ret = triggerHandlerForGesture(event, phase, LONG_TAP); 935 } 936 937 // CLICK / TAP (if the above didn't cancel) 938 else if(didTap() && ret!==false) { 939 //Trigger the tap event.. 940 ret = triggerHandlerForGesture(event, phase, TAP); 941 } 942 } 943 944 945 946 // If we are cancelling the gesture, then manually trigger the reset handler 947 if (phase === PHASE_CANCEL) { 948 touchCancel(event); 949 } 950 951 // If we are ending the gesture, then manually trigger the reset handler IF all fingers are off 952 if(phase === PHASE_END) { 953 //If we support touch, then check that all fingers are off before we cancel 954 if (SUPPORTS_TOUCH) { 955 if(event.touches.length==0) { 956 touchCancel(event); 957 } 958 } 959 else { 960 touchCancel(event); 961 } 962 } 963 964 return ret; 965 } 966 967 968 969 /** 970 * Trigger the relevant event handler 971 * The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down" 972 * @param {object} event the original event object 973 * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases} 974 * @param {string} gesture the gesture to trigger a handler for : PINCH or SWIPE {@link $.fn.swipe.gestures} 975 * @return Boolean False, to indicate that the event should stop propagation, or void. 976 * @inner 977 */ 978 function triggerHandlerForGesture(event, phase, gesture) { 979 980 var ret=undefined; 981 982 //SWIPES.... 983 if(gesture==SWIPE) { 984 //Trigger status every time.. 985 986 //Trigger the event... 987 $element.trigger('swipeStatus', [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData]); 988 989 //Fire the callback 990 if (options.swipeStatus) { 991 ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData); 992 //If the status cancels, then dont run the subsequent event handlers.. 993 if(ret===false) return false;
vendor: 17,361 bytes, lines 994-1592
994 } 995 996 997 998 999 if (phase == PHASE_END && validateSwipe()) { 1000 //Fire the catch all event 1001 $element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData]); 1002 1003 //Fire catch all callback 1004 if (options.swipe) { 1005 ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData); 1006 //If the status cancels, then dont run the subsequent event handlers.. 1007 if(ret===false) return false; 1008 } 1009 1010 //trigger direction specific event handlers 1011 switch (direction) { 1012 case LEFT: 1013 //Trigger the event 1014 $element.trigger('swipeLeft', [direction, distance, duration, fingerCount, fingerData]); 1015 1016 //Fire the callback 1017 if (options.swipeLeft) { 1018 ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount, fingerData); 1019 } 1020 break; 1021 1022 case RIGHT: 1023 //Trigger the event 1024 $element.trigger('swipeRight', [direction, distance, duration, fingerCount, fingerData]); 1025 1026 //Fire the callback 1027 if (options.swipeRight) { 1028 ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount, fingerData); 1029 } 1030 break; 1031 1032 case UP: 1033 //Trigger the event 1034 $element.trigger('swipeUp', [direction, distance, duration, fingerCount, fingerData]); 1035 1036 //Fire the callback 1037 if (options.swipeUp) { 1038 ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount, fingerData); 1039 } 1040 break; 1041 1042 case DOWN: 1043 //Trigger the event 1044 $element.trigger('swipeDown', [direction, distance, duration, fingerCount, fingerData]); 1045 1046 //Fire the callback 1047 if (options.swipeDown) { 1048 ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount, fingerData); 1049 } 1050 break; 1051 } 1052 } 1053 } 1054 1055 1056 //PINCHES.... 1057 if(gesture==PINCH) { 1058 //Trigger the event 1059 $element.trigger('pinchStatus', [phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); 1060 1061 //Fire the callback 1062 if (options.pinchStatus) { 1063 ret = options.pinchStatus.call($element, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); 1064 //If the status cancels, then dont run the subsequent event handlers.. 1065 if(ret===false) return false; 1066 } 1067 1068 if(phase==PHASE_END && validatePinch()) { 1069 1070 switch (pinchDirection) { 1071 case IN: 1072 //Trigger the event 1073 $element.trigger('pinchIn', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); 1074 1075 //Fire the callback 1076 if (options.pinchIn) { 1077 ret = options.pinchIn.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); 1078 } 1079 break; 1080 1081 case OUT: 1082 //Trigger the event 1083 $element.trigger('pinchOut', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); 1084 1085 //Fire the callback 1086 if (options.pinchOut) { 1087 ret = options.pinchOut.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); 1088 } 1089 break; 1090 } 1091 } 1092 } 1093 1094 1095 1096 1097 1098 if(gesture==TAP) { 1099 if(phase === PHASE_CANCEL || phase === PHASE_END) { 1100 1101 1102 //Cancel any existing double tap 1103 clearTimeout(singleTapTimeout); 1104 //Cancel hold timeout 1105 clearTimeout(holdTimeout); 1106 1107 //If we are also looking for doubelTaps, wait incase this is one... 1108 if(hasDoubleTap() && !inDoubleTap()) { 1109 //Cache the time of this tap 1110 doubleTapStartTime = getTimeStamp(); 1111 1112 //Now wait for the double tap timeout, and trigger this single tap 1113 //if its not cancelled by a double tap 1114 singleTapTimeout = setTimeout($.proxy(function() { 1115 doubleTapStartTime=null; 1116 //Trigger the event 1117 $element.trigger('tap', [event.target]); 1118 1119 1120 //Fire the callback 1121 if(options.tap) { 1122 ret = options.tap.call($element, event, event.target); 1123 } 1124 }, this), options.doubleTapThreshold ); 1125 1126 } else { 1127 doubleTapStartTime=null; 1128 1129 //Trigger the event 1130 $element.trigger('tap', [event.target]); 1131 1132 1133 //Fire the callback 1134 if(options.tap) { 1135 ret = options.tap.call($element, event, event.target); 1136 } 1137 } 1138 } 1139 } 1140 1141 else if (gesture==DOUBLE_TAP) { 1142 if(phase === PHASE_CANCEL || phase === PHASE_END) { 1143 //Cancel any pending singletap 1144 clearTimeout(singleTapTimeout); 1145 doubleTapStartTime=null; 1146 1147 //Trigger the event 1148 $element.trigger('doubletap', [event.target]); 1149 1150 //Fire the callback 1151 if(options.doubleTap) { 1152 ret = options.doubleTap.call($element, event, event.target); 1153 } 1154 } 1155 } 1156 1157 else if (gesture==LONG_TAP) { 1158 if(phase === PHASE_CANCEL || phase === PHASE_END) { 1159 //Cancel any pending singletap (shouldnt be one) 1160 clearTimeout(singleTapTimeout); 1161 doubleTapStartTime=null; 1162 1163 //Trigger the event 1164 $element.trigger('longtap', [event.target]); 1165 1166 //Fire the callback 1167 if(options.longTap) { 1168 ret = options.longTap.call($element, event, event.target); 1169 } 1170 } 1171 } 1172 1173 return ret; 1174 } 1175 1176 1177 1178 1179 // 1180 // GESTURE VALIDATION 1181 // 1182 1183 /** 1184 * Checks the user has swipe far enough 1185 * @return Boolean if <code>threshold</code> has been set, return true if the threshold was met, else false. 1186 * If no threshold was set, then we return true. 1187 * @inner 1188 */ 1189 function validateSwipeDistance() { 1190 var valid = true; 1191 //If we made it past the min swipe distance.. 1192 if (options.threshold !== null) { 1193 valid = distance >= options.threshold; 1194 } 1195 1196 return valid; 1197 } 1198 1199 /** 1200 * Checks the user has swiped back to cancel. 1201 * @return Boolean if <code>cancelThreshold</code> has been set, return true if the cancelThreshold was met, else false. 1202 * If no cancelThreshold was set, then we return true. 1203 * @inner 1204 */ 1205 function didSwipeBackToCancel() { 1206 var cancelled = false; 1207 if(options.cancelThreshold !== null && direction !==null) { 1208 cancelled = (getMaxDistance( direction ) - distance) >= options.cancelThreshold; 1209 } 1210 1211 return cancelled; 1212 } 1213 1214 /** 1215 * Checks the user has pinched far enough 1216 * @return Boolean if <code>pinchThreshold</code> has been set, return true if the threshold was met, else false. 1217 * If no threshold was set, then we return true. 1218 * @inner 1219 */ 1220 function validatePinchDistance() { 1221 if (options.pinchThreshold !== null) { 1222 return pinchDistance >= options.pinchThreshold; 1223 } 1224 return true; 1225 } 1226 1227 /** 1228 * Checks that the time taken to swipe meets the minimum / maximum requirements 1229 * @return Boolean 1230 * @inner 1231 */ 1232 function validateSwipeTime() { 1233 var result; 1234 //If no time set, then return true 1235 1236 if (options.maxTimeThreshold) { 1237 if (duration >= options.maxTimeThreshold) { 1238 result = false; 1239 } else { 1240 result = true; 1241 } 1242 } 1243 else { 1244 result = true; 1245 } 1246 1247 return result; 1248 } 1249 1250 1251 1252 /** 1253 * Checks direction of the swipe and the value allowPageScroll to see if we should allow or prevent the default behaviour from occurring. 1254 * This will essentially allow page scrolling or not when the user is swiping on a touchSwipe object. 1255 * @param {object} jqEvent The normalised jQuery representation of the event object. 1256 * @param {string} direction The direction of the event. See {@link $.fn.swipe.directions} 1257 * @see $.fn.swipe.directions 1258 * @inner 1259 */ 1260 function validateDefaultEvent(jqEvent, direction) { 1261 1262 1263 if( options.preventDefaultEvents === false ) { 1264 return; 1265 } 1266 1267 if (options.allowPageScroll === NONE) { 1268 jqEvent.preventDefault(); 1269 } else { 1270 var auto = options.allowPageScroll === AUTO; 1271 1272 switch (direction) { 1273 case LEFT: 1274 if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) { 1275 jqEvent.preventDefault(); 1276 } 1277 break; 1278 1279 case RIGHT: 1280 if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) { 1281 jqEvent.preventDefault(); 1282 } 1283 break; 1284 1285 case UP: 1286 if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) { 1287 jqEvent.preventDefault(); 1288 } 1289 break; 1290 1291 case DOWN: 1292 if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) { 1293 jqEvent.preventDefault(); 1294 } 1295 break; 1296 } 1297 } 1298 1299 } 1300 1301 1302 // PINCHES 1303 /** 1304 * Returns true of the current pinch meets the thresholds 1305 * @return Boolean 1306 * @inner 1307 */ 1308 function validatePinch() { 1309 var hasCorrectFingerCount = validateFingers(); 1310 var hasEndPoint = validateEndPoint(); 1311 var hasCorrectDistance = validatePinchDistance(); 1312 return hasCorrectFingerCount && hasEndPoint && hasCorrectDistance; 1313 1314 } 1315 1316 /** 1317 * Returns true if any Pinch events have been registered 1318 * @return Boolean 1319 * @inner 1320 */ 1321 function hasPinches() { 1322 //Enure we dont return 0 or null for false values 1323 return !!(options.pinchStatus || options.pinchIn || options.pinchOut); 1324 } 1325 1326 /** 1327 * Returns true if we are detecting pinches, and have one 1328 * @return Boolean 1329 * @inner 1330 */ 1331 function didPinch() { 1332 //Enure we dont return 0 or null for false values 1333 return !!(validatePinch() && hasPinches()); 1334 } 1335 1336 1337 1338 1339 // SWIPES 1340 /** 1341 * Returns true if the current swipe meets the thresholds 1342 * @return Boolean 1343 * @inner 1344 */ 1345 function validateSwipe() { 1346 //Check validity of swipe 1347 var hasValidTime = validateSwipeTime(); 1348 var hasValidDistance = validateSwipeDistance(); 1349 var hasCorrectFingerCount = validateFingers(); 1350 var hasEndPoint = validateEndPoint(); 1351 var didCancel = didSwipeBackToCancel(); 1352 1353 // if the user swiped more than the minimum length, perform the appropriate action 1354 // hasValidDistance is null when no distance is set 1355 var valid = !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime; 1356 1357 return valid; 1358 } 1359 1360 /** 1361 * Returns true if any Swipe events have been registered 1362 * @return Boolean 1363 * @inner 1364 */ 1365 function hasSwipes() { 1366 //Enure we dont return 0 or null for false values 1367 return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown); 1368 } 1369 1370 1371 /** 1372 * Returns true if we are detecting swipes and have one 1373 * @return Boolean 1374 * @inner 1375 */ 1376 function didSwipe() { 1377 //Enure we dont return 0 or null for false values 1378 return !!(validateSwipe() && hasSwipes()); 1379 } 1380 1381 /** 1382 * Returns true if we have matched the number of fingers we are looking for 1383 * @return Boolean 1384 * @inner 1385 */ 1386 function validateFingers() { 1387 //The number of fingers we want were matched, or on desktop we ignore 1388 return ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH); 1389 } 1390 1391 /** 1392 * Returns true if we have an end point for the swipe 1393 * @return Boolean 1394 * @inner 1395 */ 1396 function validateEndPoint() { 1397 //We have an end value for the finger 1398 return fingerData[0].end.x !== 0; 1399 } 1400 1401 // TAP / CLICK 1402 /** 1403 * Returns true if a click / tap events have been registered 1404 * @return Boolean 1405 * @inner 1406 */ 1407 function hasTap() { 1408 //Enure we dont return 0 or null for false values 1409 return !!(options.tap) ; 1410 } 1411 1412 /** 1413 * Returns true if a double tap events have been registered 1414 * @return Boolean 1415 * @inner 1416 */ 1417 function hasDoubleTap() { 1418 //Enure we dont return 0 or null for false values 1419 return !!(options.doubleTap) ; 1420 } 1421 1422 /** 1423 * Returns true if any long tap events have been registered 1424 * @return Boolean 1425 * @inner 1426 */ 1427 function hasLongTap() { 1428 //Enure we dont return 0 or null for false values 1429 return !!(options.longTap) ; 1430 } 1431 1432 /** 1433 * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past. 1434 * @return Boolean 1435 * @inner 1436 */ 1437 function validateDoubleTap() { 1438 if(doubleTapStartTime==null){ 1439 return false; 1440 } 1441 var now = getTimeStamp(); 1442 return (hasDoubleTap() && ((now-doubleTapStartTime) <= options.doubleTapThreshold)); 1443 } 1444 1445 /** 1446 * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past. 1447 * @return Boolean 1448 * @inner 1449 */ 1450 function inDoubleTap() { 1451 return validateDoubleTap(); 1452 } 1453 1454 1455 /** 1456 * Returns true if we have a valid tap 1457 * @return Boolean 1458 * @inner 1459 */ 1460 function validateTap() { 1461 return ((fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold)); 1462 } 1463 1464 /** 1465 * Returns true if we have a valid long tap 1466 * @return Boolean 1467 * @inner 1468 */ 1469 function validateLongTap() { 1470 //slight threshold on moving finger 1471 return ((duration > options.longTapThreshold) && (distance < DOUBLE_TAP_THRESHOLD)); 1472 } 1473 1474 /** 1475 * Returns true if we are detecting taps and have one 1476 * @return Boolean 1477 * @inner 1478 */ 1479 function didTap() { 1480 //Enure we dont return 0 or null for false values 1481 return !!(validateTap() && hasTap()); 1482 } 1483 1484 1485 /** 1486 * Returns true if we are detecting double taps and have one 1487 * @return Boolean 1488 * @inner 1489 */ 1490 function didDoubleTap() { 1491 //Enure we dont return 0 or null for false values 1492 return !!(validateDoubleTap() && hasDoubleTap()); 1493 } 1494 1495 /** 1496 * Returns true if we are detecting long taps and have one 1497 * @return Boolean 1498 * @inner 1499 */ 1500 function didLongTap() { 1501 //Enure we dont return 0 or null for false values 1502 return !!(validateLongTap() && hasLongTap()); 1503 } 1504 1505 1506 1507 1508 // MULTI FINGER TOUCH 1509 /** 1510 * Starts tracking the time between 2 finger releases, and keeps track of how many fingers we initially had up 1511 * @inner 1512 */ 1513 function startMultiFingerRelease() { 1514 previousTouchEndTime = getTimeStamp(); 1515 previousTouchFingerCount = event.touches.length+1; 1516 } 1517 1518 /** 1519 * Cancels the tracking of time between 2 finger releases, and resets counters 1520 * @inner 1521 */ 1522 function cancelMultiFingerRelease() { 1523 previousTouchEndTime = 0; 1524 previousTouchFingerCount = 0; 1525 } 1526 1527 /** 1528 * Checks if we are in the threshold between 2 fingers being released 1529 * @return Boolean 1530 * @inner 1531 */ 1532 function inMultiFingerRelease() { 1533 1534 var withinThreshold = false; 1535 1536 if(previousTouchEndTime) { 1537 var diff = getTimeStamp() - previousTouchEndTime 1538 if( diff<=options.fingerReleaseThreshold ) { 1539 withinThreshold = true; 1540 } 1541 } 1542 1543 return withinThreshold; 1544 } 1545 1546 1547 /** 1548 * gets a data flag to indicate that a touch is in progress 1549 * @return Boolean 1550 * @inner 1551 */ 1552 function getTouchInProgress() { 1553 //strict equality to ensure only true and false are returned 1554 return !!($element.data(PLUGIN_NS+'_intouch') === true); 1555 } 1556 1557 /** 1558 * Sets a data flag to indicate that a touch is in progress 1559 * @param {boolean} val The value to set the property to 1560 * @inner 1561 */ 1562 function setTouchInProgress(val) { 1563 1564 //Add or remove event listeners depending on touch status 1565 if(val===true) { 1566 $element.bind(MOVE_EV, touchMove); 1567 $element.bind(END_EV, touchEnd); 1568 1569 //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit 1570 if(LEAVE_EV) { 1571 $element.bind(LEAVE_EV, touchLeave); 1572 } 1573 } else { 1574 $element.unbind(MOVE_EV, touchMove, false); 1575 $element.unbind(END_EV, touchEnd, false); 1576 1577 //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit 1578 if(LEAVE_EV) { 1579 $element.unbind(LEAVE_EV, touchLeave, false); 1580 } 1581 } 1582 1583 1584 //strict equality to ensure only true and false can update the value 1585 $element.data(PLUGIN_NS+'_intouch', val === true); 1586 } 1587 1588 1589 /** 1590 * Creates the finger data for the touch/finger in the event object. 1591 * @param {int} index The index in the array to store the finger data (usually the order the fingers were pressed) 1592 * @param {object}
1592 evt The event object containing finger data 1593 * @return finger data object 1594 * @inner 1595 */ 1596 function createFingerData( index, evt ) { 1597 var id = evt.identifier!==undefined ? evt.identifier : 0; 1598 1599 fingerData[index].identifier = id; 1600 fingerData[index].start.x = fingerData[index].end.x = evt.pageX||evt.clientX; 1601 fingerData[index].start.y = fingerData[index].end.y = evt.pageY||evt.clientY; 1602 1603 return fingerData[index]; 1604 } 1605 1606 /** 1607 * Updates the finger data for a particular event object 1608 * @param {object} evt The event object containing the touch/finger data to upadte 1609 * @return a finger data object. 1610 * @inner 1611 */ 1612 function updateFingerData(evt) { 1613 1614 var id = evt.identifier!==undefined ? evt.identifier : 0; 1615 var f = getFingerData( id ); 1616 1617 f.end.x = evt.pageX||evt.clientX; 1618 f.end.y = evt.pageY||evt.clientY; 1619 1620 return f; 1621 } 1622 1623 /** 1624 * Returns a finger data object by its event ID. 1625 * Each touch event has an identifier property, which is used 1626 * to track repeat touches 1627 * @param {int} id The unique id of the finger in the sequence of touch events. 1628 * @return a finger data object. 1629 * @inner 1630 */ 1631 function getFingerData( id ) { 1632 for(var i=0; i<fingerData.length; i++) { 1633 if(fingerData[i].identifier == id) { 1634 return fingerData[i]; 1635 } 1636 } 1637 } 1638 1639 /** 1640 * Creats all the finger onjects and returns an array of finger data 1641 * @return Array of finger objects 1642 * @inner 1643 */ 1644 function createAllFingerData() { 1645 var fingerData=[]; 1646 for (var i=0; i<=5; i++) { 1647 fingerData.push({ 1648 start:{ x: 0, y: 0 }, 1649 end:{ x: 0, y: 0 }, 1650 identifier:0 1651 }); 1652 } 1653 1654 return fingerData; 1655 } 1656 1657 /** 1658 * Sets the maximum distance swiped in the given direction. 1659 * If the new value is lower than the current value, the max value is not changed. 1660 * @param {string} direction The direction of the swipe 1661 * @param {int} distance The distance of the swipe 1662 * @inner 1663 */ 1664 function setMaxDistance(direction, distance) { 1665 distance = Math.max(distance, getMaxDistance(direction) ); 1666 maximumsMap[direction].distance = distance; 1667 } 1668 1669 /** 1670 * gets the maximum distance swiped in the given direction. 1671 * @param {string} direction The direction of the swipe 1672 * @return int The distance of the swipe 1673 * @inner 1674 */ 1675 function getMaxDistance(direction) { 1676 if (maximumsMap[direction]) return maximumsMap[direction].distance; 1677 return undefined; 1678 } 1679 1680 /** 1681 * Creats a map of directions to maximum swiped values. 1682 * @return Object A dictionary of maximum values, indexed by direction. 1683 * @inner 1684 */ 1685 function createMaximumsData() { 1686 var maxData={}; 1687 maxData[LEFT]=createMaximumVO(LEFT); 1688 maxData[RIGHT]=createMaximumVO(RIGHT); 1689 maxData[UP]=createMaximumVO(UP); 1690 maxData[DOWN]=createMaximumVO(DOWN); 1691 1692 return maxData; 1693 } 1694 1695 /** 1696 * Creates a map maximum swiped values for a given swipe direction 1697 * @param {string} The direction that these values will be associated with 1698 * @return Object Maximum values 1699 * @inner 1700 */ 1701 function createMaximumVO(dir) { 1702 return { 1703 direction:dir, 1704 distance:0 1705 } 1706 } 1707 1708 1709 // 1710 // MATHS / UTILS 1711 // 1712 1713 /** 1714 * Calculate the duration of the swipe 1715 * @return int 1716 * @inner 1717 */ 1718 function calculateDuration() { 1719 return endTime - startTime; 1720 } 1721 1722 /** 1723 * Calculate the distance between 2 touches (pinch) 1724 * @param {point} startPoint A point object containing x and y co-ordinates 1725 * @param {point} endPoint A point object containing x and y co-ordinates 1726 * @return int; 1727 * @inner 1728 */ 1729 function calculateTouchesDistance(startPoint, endPoint) { 1730 var diffX = Math.abs(startPoint.x - endPoint.x); 1731 var diffY = Math.abs(startPoint.y - endPoint.y); 1732 1733 return Math.round(Math.sqrt(diffX*diffX+diffY*diffY)); 1734 } 1735 1736 /** 1737 * Calculate the zoom factor between the start and end distances 1738 * @param {int} startDistance Distance (between 2 fingers) the user started pinching at 1739 * @param {int} endDistance Distance (between 2 fingers) the user ended pinching at 1740 * @return float The zoom value from 0 to 1. 1741 * @inner 1742 */ 1743 function calculatePinchZoom(startDistance, endDistance) { 1744 var percent = (endDistance/startDistance) * 1; 1745 return percent.toFixed(2); 1746 } 1747 1748 1749 /** 1750 * Returns the pinch direction, either IN or OUT for the given points 1751 * @return string Either {@link $.fn.swipe.directions.IN} or {@link $.fn.swipe.directions.OUT} 1752 * @see $.fn.swipe.directions 1753 * @inner 1754 */ 1755 function calculatePinchDirection() { 1756 if(pinchZoom<1) { 1757 return OUT; 1758 } 1759 else { 1760 return IN; 1761 } 1762 } 1763 1764 1765 /** 1766 * Calculate the length / distance of the swipe 1767 * @param {point}
vendor: 5,862 bytes, lines 1767-1944
1767 startPoint A point object containing x and y co-ordinates 1768 * @param {point} endPoint A point object containing x and y co-ordinates 1769 * @return int 1770 * @inner 1771 */ 1772 function calculateDistance(startPoint, endPoint) { 1773 return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2))); 1774 } 1775 1776 /** 1777 * Calculate the angle of the swipe 1778 * @param {point} startPoint A point object containing x and y co-ordinates 1779 * @param {point} endPoint A point object containing x and y co-ordinates 1780 * @return int 1781 * @inner 1782 */ 1783 function calculateAngle(startPoint, endPoint) { 1784 var x = startPoint.x - endPoint.x; 1785 var y = endPoint.y - startPoint.y; 1786 var r = Math.atan2(y, x); //radians 1787 var angle = Math.round(r * 180 / Math.PI); //degrees 1788 1789 //ensure value is positive 1790 if (angle < 0) { 1791 angle = 360 - Math.abs(angle); 1792 } 1793 1794 return angle; 1795 } 1796 1797 /** 1798 * Calculate the direction of the swipe 1799 * This will also call calculateAngle to get the latest angle of swipe 1800 * @param {point} startPoint A point object containing x and y co-ordinates 1801 * @param {point} endPoint A point object containing x and y co-ordinates 1802 * @return string Either {@link $.fn.swipe.directions.LEFT} / {@link $.fn.swipe.directions.RIGHT} / {@link $.fn.swipe.directions.DOWN} / {@link $.fn.swipe.directions.UP} 1803 * @see $.fn.swipe.directions 1804 * @inner 1805 */ 1806 function calculateDirection(startPoint, endPoint ) { 1807 var angle = calculateAngle(startPoint, endPoint); 1808 1809 if ((angle <= 45) && (angle >= 0)) { 1810 return LEFT; 1811 } else if ((angle <= 360) && (angle >= 315)) { 1812 return LEFT; 1813 } else if ((angle >= 135) && (angle <= 225)) { 1814 return RIGHT; 1815 } else if ((angle > 45) && (angle < 135)) { 1816 return DOWN; 1817 } else { 1818 return UP; 1819 } 1820 } 1821 1822 1823 /** 1824 * Returns a MS time stamp of the current time 1825 * @return int 1826 * @inner 1827 */ 1828 function getTimeStamp() { 1829 var now = new Date(); 1830 return now.getTime(); 1831 } 1832 1833 1834 1835 /** 1836 * Returns a bounds object with left, right, top and bottom properties for the element specified. 1837 * @param {DomNode} The DOM node to get the bounds for. 1838 */ 1839 function getbounds( el ) { 1840 el = $(el); 1841 var offset = el.offset(); 1842 1843 var bounds = { 1844 left:offset.left, 1845 right:offset.left+el.outerWidth(), 1846 top:offset.top, 1847 bottom:offset.top+el.outerHeight() 1848 } 1849 1850 return bounds; 1851 } 1852 1853 1854 /** 1855 * Checks if the point object is in the bounds object. 1856 * @param {object} point A point object. 1857 * @param {int} point.x The x value of the point. 1858 * @param {int} point.y The x value of the point. 1859 * @param {object} bounds The bounds object to test 1860 * @param {int} bounds.left The leftmost value 1861 * @param {int} bounds.right The righttmost value 1862 * @param {int} bounds.top The topmost value 1863 * @param {int} bounds.bottom The bottommost value 1864 */ 1865 function isInBounds(point, bounds) { 1866 return (point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom); 1867 }; 1868 1869 1870 } 1871 1872 1873 1874 1875/** 1876 * A catch all handler that is triggered for all swipe directions. 1877 * @name $.fn.swipe#swipe 1878 * @event 1879 * @default null 1880 * @param {EventObject} event The original event object 1881 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 1882 * @param {int} distance The distance the user swiped 1883 * @param {int} duration The duration of the swipe in milliseconds 1884 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1885 * @param {object} fingerData The coordinates of fingers in event 1886 */ 1887 1888 1889 1890 1891/** 1892 * A handler that is triggered for "left" swipes. 1893 * @name $.fn.swipe#swipeLeft 1894 * @event 1895 * @default null 1896 * @param {EventObject} event The original event object 1897 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 1898 * @param {int} distance The distance the user swiped 1899 * @param {int} duration The duration of the swipe in milliseconds 1900 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1901 * @param {object} fingerData The coordinates of fingers in event 1902 */ 1903 1904/** 1905 * A handler that is triggered for "right" swipes. 1906 * @name $.fn.swipe#swipeRight 1907 * @event 1908 * @default null 1909 * @param {EventObject} event The original event object 1910 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 1911 * @param {int} distance The distance the user swiped 1912 * @param {int} duration The duration of the swipe in milliseconds 1913 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1914 * @param {object} fingerData The coordinates of fingers in event 1915 */ 1916 1917/** 1918 * A handler that is triggered for "up" swipes. 1919 * @name $.fn.swipe#swipeUp 1920 * @event 1921 * @default null 1922 * @param {EventObject} event The original event object 1923 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 1924 * @param {int} distance The distance the user swiped 1925 * @param {int} duration The duration of the swipe in milliseconds 1926 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1927 * @param {object} fingerData The coordinates of fingers in event 1928 */ 1929 1930/** 1931 * A handler that is triggered for "down" swipes. 1932 * @name $.fn.swipe#swipeDown 1933 * @event 1934 * @default null 1935 * @param {EventObject} event The original event object 1936 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 1937 * @param {int} distance The distance the user swiped 1938 * @param {int} duration The duration of the swipe in milliseconds 1939 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1940 * @param {object} fingerData The coordinates of fingers in event 1941 */ 1942 1943/** 1944 * A handler triggered for every phase of the swipe. This handler is constantly f
1944ired for the duration of the pinch. 1945 * This is triggered regardless of swipe thresholds. 1946 * @name $.fn.swipe#swipeStatus 1947 * @event 1948 * @default null 1949 * @param {EventObject} event The original event object 1950 * @param {string} phase The phase of the swipe event. See {@link $.fn.swipe.phases} 1951 * @param {string} direction The direction the user swiped in. This is null if the user has yet to move. See {@link $.fn.swipe.directions} 1952 * @param {int} distance The distance the user swiped. This is 0 if the user has yet to move. 1953 * @param {int} duration The duration of the swipe in milliseconds 1954 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1955 * @param {object} fingerData The coordinates of fingers in event 1956 */ 1957 1958/** 1959 * A handler triggered for pinch in events. 1960 * @name $.fn.swipe#pinchIn 1961 * @event 1962 * @default null 1963 * @param {EventObject} event The original event object 1964 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions} 1965 * @param {int} distance The distance the user pinched 1966 * @param {int} duration The duration of the swipe in milliseconds 1967 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1968 * @param {int} zoom The zoom/scale level the user pinched too, 0-1. 1969 * @param {object} fingerData The coordinates of fingers in event 1970 */ 1971 1972/** 1973 * A handler triggered for pinch out events. 1974 * @name $.fn.swipe#pinchOut 1975 * @event 1976 * @default null 1977 * @param {EventObject} event The original event object 1978 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions} 1979 * @param {int} distance The distance the user pinched 1980 * @param {int} duration The duration of the swipe in milliseconds 1981 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1982 * @param {int} zoom The zoom/scale level the user pinched too, 0-1. 1983 * @param {object} fingerData The coordinates of fingers in event 1984 */ 1985 1986/** 1987 * A handler triggered for all pinch events. This handler is constantly fired for the duration of the pinch. This is triggered regardless of thresholds. 1988 * @name $.fn.swipe#pinchStatus 1989 * @event 1990 * @default null 1991 * @param {EventObject} event The original event object 1992 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions} 1993 * @param {int} distance The distance the user pinched 1994 * @param {int} duration The duration of the swipe in milliseconds 1995 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1996 * @param {int} zoom The zoom/scale level the user pinched too, 0-1. 1997 * @param {object} fingerData The coordinates of fingers in event 1998 */ 1999 2000/** 2001 * A click handler triggered when a user simply clicks, rather than swipes on an element. 2002 * This is deprecated since version 1.6.2, any assignment to click will be assigned to the tap handler. 2003 * You cannot use <code>on</code> to bind to this event as the default jQ <code>click</code> event will be triggered. 2004 * Use the <code>tap</code> event instead. 2005 * @name $.fn.swipe#click 2006 * @event 2007 * @deprecated since version 1.6.2, please use {@link $.fn.swipe#tap} instead 2008 * @default null 2009 * @param {EventObject} event The original event object 2010 * @param {DomObject} target The element clicked on. 2011 */ 2012 2013 /** 2014 * A click / tap handler triggered when a user simply clicks or taps, rather than swipes on an element. 2015 * @name $.fn.swipe#tap 2016 * @event 2017 * @default null 2018 * @param {EventObject} event The original event object 2019 * @param {DomObject} target The element clicked on. 2020 */ 2021 2022/** 2023 * A double tap handler triggered when a user double clicks or taps on an element. 2024 * You can set the time delay for a double tap with the {@link $.fn.swipe.defaults#doubleTapThreshold} property. 2025 * Note: If you set both <code>doubleTap</code> and <code>tap</code> handlers, the <code>tap</code> event will be delayed by the <code>doubleTapThreshold</code> 2026 * as the script needs to check if its a double tap. 2027 * @name $.fn.swipe#doubleTap 2028 * @see $.fn.swipe.defaults#doubleTapThreshold 2029 * @event 2030 * @default null 2031 * @param {EventObject} event The original event object 2032 * @param {DomObject} target The element clicked on. 2033 */ 2034 2035 /** 2036 * A long tap handler triggered once a tap has been release if the tap was longer than the longTapThreshold. 2037 * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. 2038 * @name $.fn.swipe#longTap 2039 * @see $.fn.swipe.defaults#longTapThreshold 2040 * @event 2041 * @default null 2042 * @param {EventObject} event The original event object 2043 * @param {DomObject} target The element clicked on. 2044 */ 2045 2046 /** 2047 * A hold tap handler triggered as soon as the longTapThreshold is reached 2048 * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. 2049 * @name $.fn.swipe#hold 2050 * @see $.fn.swipe.defaults#longTapThreshold 2051 * @event 2052 * @default null 2053 * @param {EventObject} event The original event object 2054 * @param {DomObject} target The element clicked on. 2055 */ 2056 2057}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.