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