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