1var settings_ankerpunkte = true; // true/false 2var settings_buttonup = true; // true/false 3var settings_autotarget = true; // true/false 4var settings_iframe2video = true; // true/false 5var settings_countup = true; // true/false 6var settings_b3slider = true; // true/false 7var settings_autotarget = true; // true/false 8var settings_immoautoformfill = true; // true/false 9var settings_potrait_no_title_popup = true; // true/false 10 11/*! 12 * 13 * https://raw.githubusercontent.com/mattbryson/TouchSwipe-Jquery-Plugin/master/jquery.touchSwipe.js 14 * 15 * 16 * @fileOverview TouchSwipe - jQuery Plugin 17 * @version 1.6.18 18 * 19 * @author Matt Bryson http://www.github.com/mattbryson 20 * @see https://github.com/mattbryson/TouchSwipe-Jquery-Plugin 21 * @see http://labs.rampinteractive.co.uk/touchSwipe/ 22 * @see http://plugins.jquery.com/project/touchSwipe 23 * @license 24 * Copyright (c) 2010-2015 Matt Bryson 25 * Dual licensed under the MIT or GPL Version 2 licenses. 26 * 27 */ 28 29/* 30 * 31 * Changelog 32 * $Date: 2010-12-12 (Wed, 12 Dec 2010) $ 33 * $version: 1.0.0 34 * $version: 1.0.1 - removed multibyte comments 35 * 36 * $Date: 2011-21-02 (Mon, 21 Feb 2011) $ 37 * $version: 1.1.0 - added allowPageScroll property to allow swiping and scrolling of page 38 * - changed handler signatures so one handler can be used for multiple events 39 * $Date: 2011-23-02 (Wed, 23 Feb 2011) $ 40 * $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. 41 * - 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. 42 * $version: 1.2.1 - removed console log! 43 * 44 * $version: 1.2.2 - Fixed bug where scope was not preserved in callback methods. 45 * 46 * $Date: 2011-28-04 (Thurs, 28 April 2011) $ 47 * $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. 48 * 49 * $Date: 2011-27-09 (Tues, 27 September 2011) $
50 * $version: 1.2.5 - Added support for testing swipes with mouse on desktop browser (thanks to https://github.com/joelhy) 51 * 52 * $Date: 2012-14-05 (Mon, 14 May 2012) $ 53 * $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 54 * 55 * $Date: 2012-05-06 (Tues, 05 June 2012) $ 56 * $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. 57 * 58 * $Date: 2012-05-06 (Tues, 05 June 2012) $ 59 * $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. 60 * 61 * $Date: 2012-06-06 (Wed, 06 June 2012) $ 62 * $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 63 * 64 * $Date: 2012-05-06 (Fri, 05 June 2012) $ 65 * $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. 66 * 67 * $Date: 2012-29-07 (Sun, 29 July 2012) $ 68 * $version: 1.3.2 - Added fallbackToMouseEvents option to NOT capture mouse events on non touch devices. 69 * - Added "all" fingers value to the fingers property, so any combination of fingers triggers the swipe, allowing event handlers to check the finger count 70 * 71 * $Date: 2012-09-08 (Thurs, 9 Aug 2012) $ 72 * $version: 1.3.3 - Code tidy prep for minefied version 73 * 74 * $Date: 2012-04-10 (wed, 4 Oct 2012) $ 75 * $version: 1.4.0 - Added pinch support, pinchIn and pinchOut 76 * 77 * $Date: 2012-11-10 (Thurs, 11 Oct 2012) $ 78 * $version: 1.5.0 - Added excludedElements, a jquery selector that specifies child elements that do NOT trigger swipes. By default, this is .noSwipe 79 * 80 * $Date: 2012-22-10 (Mon, 22 Oct 2012) $ 81 * $version: 1.5.1 - Fixed bug with jQuery 1.8 and trailing comma in excludedElements 82 * - Fixed bug with IE and eventPreventDefault() 83 * $Date: 2013-01-12 (Fri, 12 Jan 2013) $ 84 * $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. 85 * - made the demo site all static local HTML pages so they can be run locally by a developer 86 * - added jsDoc comments and added documentation for the plugin 87 * - code tidy 88 * - added triggerOnTouchLeave property that will end the event when the user swipes off the element. 89 * $Date: 2013-03-23 (Sat, 23 Mar 2013) $
90 * $version: 1.6.1 - Added support for ie8 touch events 91 * $version: 1.6.2 - Added support for events binding with on / off / bind in jQ for all callback names. 92 * - Deprecated the 'click' handler in favour of tap. 93 * - added cancelThreshold property 94 * - added option method to update init options at runtime 95 * $version 1.6.3 - added doubletap, longtap events and longTapThreshold, doubleTapThreshold property 96 * 97 * $Date: 2013-04-04 (Thurs, 04 April 2013) $ 98 * $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. 99 * 100 * $Date: 2013-08-24 (Sat, 24 Aug 2013) $ 101 * $version 1.6.5 - Merged a few pull requests fixing various bugs, added AMD support. 102 * 103 * $Date: 2014-06-04 (Wed, 04 June 2014) $ 104 * $version 1.6.6 - Merge of pull requests. 105 * - IE10 touch support 106 * - Only prevent default event handling on valid swipe 107 * - Separate license/changelog comment 108 * - Detect if the swipe is valid at the end of the touch event. 109 * - Pass fingerdata to event handlers. 110 * - Add 'hold' gesture 111 * - Be more tolerant about the tap distance 112 * - Typos and minor fixes 113 * 114 * $Date: 2015-22-01 (Thurs, 22 Jan 2015) $ 115 * $version 1.6.7 - Added patch from https://github.com/mattbryson/TouchSwipe-Jquery-Plugin/issues/206 to fix memory leak 116 * 117 * $Date: 2015-2-2 (Mon, 2 Feb 2015) $ 118 * $version 1.6.8 - Added preventDefaultEvents option to proxy events regardless. 119 * - Fixed issue with swipe and pinch not triggering at the same time 120 * 121 * $Date: 2015-9-6 (Tues, 9 June 2015) $ 122 * $version 1.6.9 - Added PR from jdalton/hybrid to fix pointer events 123 * - Added scrolling demo 124 * - Added version property to plugin 125 * 126 * $Date: 2015-1-10 (Wed, 1 October 2015) $ 127 * $version 1.6.10 - Added PR from beatspace to fix tap events 128 * $version 1.6.11 - Added PRs from indri-indri ( Doc tidyup), kkirsche ( Bower tidy up ), UziTech (preventDefaultEvents fixes ) 129 * - Allowed setting multiple options via .swipe("options", options_hash) and more simply .swipe(options_hash) or exisitng instances 130 * $version 1.6.12 - Fixed bug with multi finger releases above 2 not triggering events 131 * 132 * $Date: 2015-12-18 (Fri, 18 December 2015) $ 133 * $version 1.6.13 - Added PRs 134 * - Fixed #267 allowPageScroll not working correctly 135 * $version 1.6.14 - Fixed #220 / #248 doubletap not firing with swipes, #223 commonJS compatible 136 * $version 1.6.15 - More bug fixes 137 * 138 * $Date: 2016-04-29 (Fri, 29 April 2016) $ 139 * $version 1.6.16 - Swipes with 0 distance now allow default events to trigger. So tapping any form elements or A tags will allow default interaction, but swiping will trigger a swipe. 140 Removed the a, input, select etc from the excluded Children list as the 0 distance tap solves that issue. 141* $Date: 2016-05-19 (Fri, 29 April 2016) $ 142* $version 1.6.17 - Fixed context issue when calling instance methods via $("selector").swipe("method"); 143* $version 1.6.18 - now honors fallbackToMouseEvents=false for MS Pointer events when a Mouse is used. 144 145 */ 146 147/** 148 * See (http://jquery.com/). 149 * @name $ 150 * @class 151 * See the jQuery Library (http://jquery.com/) for full details. This just 152 * documents the function and classes that are added to jQuery by this plug-in. 153 */ 154 155/** 156 * See (http://jquery.com/) 157 * @name fn 158 * @class 159 * See the jQuery Library (http://jquery.com/) for full details. This just 160 * documents the function and classes that are added to jQuery by this plug-in. 161 * @memberOf $ 162 */ 163 164 165(function (factory) { 166 if (typeof define === 'function' && define.amd && define.amd.jQuery) { 167 // AMD. Register as anonymous module. 168 define(['jquery'], factory); 169 } else if (typeof module !== 'undefined' && module.exports) { 170 // CommonJS Module 171 factory(require("jquery")); 172 } else { 173 // Browser globals. 174 factory(jQuery); 175 } 176}(function ($) { 177 "use strict"; 178 179 //Constants 180 var VERSION = "1.6.18", 181 LEFT = "left", 182 RIGHT = "right", 183 UP = "up", 184 DOWN = "down", 185 IN = "in", 186 OUT = "out", 187 188 NONE = "none", 189 AUTO = "auto", 190 191 SWIPE = "swipe", 192 PINCH = "pinch", 193 TAP = "tap", 194 DOUBLE_TAP = "doubletap", 195 LONG_TAP = "longtap", 196 HOLD = "hold", 197 198 HORIZONTAL = "horizontal", 199 VERTICAL = "vertical", 200 201 ALL_FINGERS = "all", 202 203 DOUBLE_TAP_THRESHOLD = 10, 204 205 PHASE_START = "start", 206 PHASE_MOVE = "move", 207 PHASE_END = "end", 208 PHASE_CANCEL = "cancel", 209 210 SUPPORTS_TOUCH = 'ontouchstart' in window, 211 212 SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.PointerEvent && !SUPPORTS_TOUCH, 213 214 SUPPORTS_POINTER = (window.PointerEvent || window.navigator.msPointerEnabled) && !SUPPORTS_TOUCH, 215 216 PLUGIN_NS = 'TouchSwipe'; 217 218 219 220 /** 221 * The default configuration, and available options to configure touch swipe with. 222 * You can set the default values by updating any of the properties prior to instantiation. 223 * @name $.fn.swipe.defaults 224 * @namespace 225 * @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. 226 * @property {int} [threshold=75] The number of pixels that the user must move their finger by before it is considered a swipe. 227 * @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. 228 * @property {int} [pinchThreshold=20] The number of pixels that the user must pinch their finger by before it is considered a pinch. 229 * @property {int} [maxTimeThreshold=null] Time, in milliseconds, between touchStart and touchEnd must NOT exceed in order to be considered a swipe. 230 * @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. 231 * @property {int} [longTapThreshold=500] Time in milliseconds between tap and release for a long tap 232 * @property {int} [doubleTapThreshold=200] Time in milliseconds between 2 taps to count as a double tap 233 * @property {function} [swipe=null] A handler to catch all swipes. See {@link $.fn.swipe#event:swipe} 234 * @property {function} [swipeLeft=null] A handler that is triggered for "left" swipes. See {@link $.fn.swipe#event:swipeLeft} 235 * @property {function} [swipeRight=null] A handler that is triggered for "right" swipes. See {@link $.fn.swipe#event:swipeRight} 236 * @property {function} [swipeUp=null] A handler that is triggered for "up" swipes. See {@link $.fn.swipe#event:swipeUp} 237 * @property {function} [swipeDown=null] A handler that is triggered for "down" swipes. See {@link $.fn.swipe#event:swipeDown} 238 * @property {function} [swipeStatus=null] A handler triggered for every phase of the swipe. See {@link $.fn.swipe#event:swipeStatus} 239 * @property {function} [pinchIn=null] A handler triggered for pinch in events. See {@link $.fn.swipe#event:pinchIn} 240 * @property {function} [pinchOut=null] A handler triggered for pinch out events. See {@link $.fn.swipe#event:pinchOut} 241 * @property {function} [pinchStatus=null] A handler triggered for every phase of a pinch. See {@link $.fn.swipe#event:pinchStatus} 242 * @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. 243 * @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} 244 * @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} 245 * @property (function) [hold=null] A handler triggered when a user reaches longTapThreshold on the item. See {@link $.fn.swipe.defaults#longTapThreshold} 246 * @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. 247 * @property {boolean} [triggerOnTouchLeave=false] If true, then when the user leaves the swipe object, the swipe will end and trigger appropriate handlers. 248 * @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/> 249 <code>"auto"</code> : all undefined swipes will cause the page to scroll in that direction. <br/> 250 <code>"none"</code> : the page will not scroll when user swipes. <br/> 251 <code>"horizontal"</code> : will force page to scroll on horizontal swipes. <br/> 252 <code>"vertical"</code> : will force page to scroll on vertical swipes. <br/> 253 * @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 touch devices. 254 * @property {string} [excludedElements=".noSwipe"] A jquery selector that specifies child elements that do NOT trigger swipes. By default this excludes elements with the class .noSwipe . 255 * @property {boolean} [preventDefaultEvents=true] by default default events are cancelled, so the page doesn't move. You can disable this so both native events fire as well as your handlers. 256 257 */ 258 var defaults = { 259 fingers: 1, 260 threshold: 75, 261 cancelThreshold: null, 262 pinchThreshold: 20, 263 maxTimeThreshold: null, 264 fingerReleaseThreshold: 250, 265 longTapThreshold: 500, 266 doubleTapThreshold: 200, 267 swipe: null, 268 swipeLeft: null, 269 swipeRight: null, 270 swipeUp: null, 271 swipeDown: null, 272 swipeStatus: null, 273 pinchIn: null, 274 pinchOut: null, 275 pinchStatus: null, 276 click: null, //Deprecated since 1.6.2 277 tap: null, 278 doubleTap: null, 279 longTap: null, 280 hold: null, 281 triggerOnTouchEnd: true, 282 triggerOnTouchLeave: false, 283 allowPageScroll: "auto", 284 fallbackToMouseEvents: true,
vendor: 62,077 bytes, lines 285-1912
285 excludedElements: ".noSwipe", 286 preventDefaultEvents: true 287 }; 288 289 290 291 /** 292 * Applies TouchSwipe behaviour to one or more jQuery objects. 293 * The TouchSwipe plugin can be instantiated via this method, or methods within 294 * TouchSwipe can be executed via this method as per jQuery plugin architecture. 295 * An existing plugin can have its options changed simply by re calling .swipe(options) 296 * @see TouchSwipe 297 * @class 298 * @param {Mixed} method If the current DOMNode is a TouchSwipe object, and <code>method</code> is a TouchSwipe method, then 299 * the <code>method</code> is executed, and any following arguments are passed to the TouchSwipe method. 300 * If <code>method</code> is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the 301 * configuration properties defined in the object. See TouchSwipe 302 * 303 */ 304 $.fn.swipe = function (method) { 305 var $this = $(this), 306 plugin = $this.data(PLUGIN_NS); 307 308 //Check if we are already instantiated and trying to execute a method 309 if (plugin && typeof method === 'string') { 310 if (plugin[method]) { 311 return plugin[method].apply(plugin, Array.prototype.slice.call(arguments, 1)); 312 } else { 313 $.error('Method ' + method + ' does not exist on jQuery.swipe'); 314 } 315 } 316 317 //Else update existing plugin with new options hash 318 else if (plugin && typeof method === 'object') { 319 plugin['option'].apply(plugin, arguments); 320 } 321 322 //Else not instantiated and trying to pass init object (or nothing) 323 else if (!plugin && (typeof method === 'object' || !method)) { 324 return init.apply(this, arguments); 325 } 326 327 return $this; 328 }; 329 330 /** 331 * The version of the plugin 332 * @readonly 333 */ 334 $.fn.swipe.version = VERSION; 335 336 337 338 //Expose our defaults so a user could override the plugin defaults 339 $.fn.swipe.defaults = defaults; 340 341 /** 342 * The phases that a touch event goes through. The <code>phase</code> is passed to the event handlers. 343 * These properties are read only, attempting to change them will not alter the values passed to the event handlers. 344 * @namespace 345 * @readonly 346 * @property {string} PHASE_START Constant indicating the start phase of the touch event. Value is <code>"start"</code>. 347 * @property {string} PHASE_MOVE Constant indicating the move phase of the touch event. Value is <code>"move"</code>. 348 * @property {string} PHASE_END Constant indicating the end phase of the touch event. Value is <code>"end"</code>. 349 * @property {string} PHASE_CANCEL Constant indicating the cancel phase of the touch event. Value is <code>"cancel"</code>. 350 */ 351 $.fn.swipe.phases = { 352 PHASE_START: PHASE_START, 353 PHASE_MOVE: PHASE_MOVE, 354 PHASE_END: PHASE_END, 355 PHASE_CANCEL: PHASE_CANCEL 356 }; 357 358 /** 359 * The direction constants that are passed to the event handlers. 360 * These properties are read only, attempting to change them will not alter the values passed to the event handlers. 361 * @namespace 362 * @readonly 363 * @property {string} LEFT Constant indicating the left direction. Value is <code>"left"</code>. 364 * @property {string} RIGHT Constant indicating the right direction. Value is <code>"right"</code>. 365 * @property {string} UP Constant indicating the up direction. Value is <code>"up"</code>. 366 * @property {string} DOWN Constant indicating the down direction. Value is <code>"cancel"</code>. 367 * @property {string} IN Constant indicating the in direction. Value is <code>"in"</code>. 368 * @property {string} OUT Constant indicating the out direction. Value is <code>"out"</code>. 369 */ 370 $.fn.swipe.directions = { 371 LEFT: LEFT, 372 RIGHT: RIGHT, 373 UP: UP, 374 DOWN: DOWN, 375 IN: IN, 376 OUT: OUT 377 }; 378 379 /** 380 * The page scroll constants that can be used to set the value of <code>allowPageScroll</code> option 381 * These properties are read only 382 * @namespace 383 * @readonly 384 * @see $.fn.swipe.defaults#allowPageScroll 385 * @property {string} NONE Constant indicating no page scrolling is allowed. Value is <code>"none"</code>. 386 * @property {string} HORIZONTAL Constant indicating horizontal page scrolling is allowed. Value is <code>"horizontal"</code>. 387 * @property {string} VERTICAL Constant indicating vertical page scrolling is allowed. Value is <code>"vertical"</code>. 388 * @property {string} AUTO Constant indicating either horizontal or vertical will be allowed, depending on the swipe handlers registered. Value is <code>"auto"</code>. 389 */ 390 $.fn.swipe.pageScroll = { 391 NONE: NONE, 392 HORIZONTAL: HORIZONTAL, 393 VERTICAL: VERTICAL, 394 AUTO: AUTO 395 }; 396 397 /** 398 * Constants representing the number of fingers used in a swipe. These are used to set both the value of <code>fingers</code> in the 399 * options object, as well as the value of the <code>fingers</code> event property. 400 * These properties are read only, attempting to change them will not alter the values passed to the event handlers. 401 * @namespace 402 * @readonly 403 * @see $.fn.swipe.defaults#fingers 404 * @property {string} ONE Constant indicating 1 finger is to be detected / was detected. Value is <code>1</code>. 405 * @property {string} TWO Constant indicating 2 fingers are to be detected / were detected. Value is <code>2</code>. 406 * @property {string} THREE Constant indicating 3 finger are to be detected / were detected. Value is <code>3</code>. 407 * @property {string} FOUR Constant indicating 4 finger are to be detected / were detected. Not all devices support this. Value is <code>4</code>. 408 * @property {string} FIVE Constant indicating 5 finger are to be detected / were detected. Not all devices support this. Value is <code>5</code>. 409 * @property {string} ALL Constant indicating any combination of finger are to be detected. Value is <code>"all"</code>. 410 */ 411 $.fn.swipe.fingers = { 412 ONE: 1, 413 TWO: 2, 414 THREE: 3, 415 FOUR: 4, 416 FIVE: 5, 417 ALL: ALL_FINGERS 418 }; 419 420 /** 421 * Initialise the plugin for each DOM element matched 422 * This creates a new instance of the main TouchSwipe class for each DOM element, and then 423 * saves a reference to that instance in the elements data property. 424 * @internal 425 */ 426 function init(options) { 427 //Prep and extend the options 428 if (options && (options.allowPageScroll === undefined && (options.swipe !== undefined || options.swipeStatus !== undefined))) { 429 options.allowPageScroll = NONE; 430 } 431 432 //Check for deprecated options 433 //Ensure that any old click handlers are assigned to the new tap, unless we have a tap 434 if (options.click !== undefined && options.tap === undefined) { 435 options.tap = options.click; 436 } 437 438 if (!options) { 439 options = {}; 440 } 441 442 //pass empty object so we dont modify the defaults 443 options = $.extend({}, $.fn.swipe.defaults, options); 444 445 //For each element instantiate the plugin 446 return this.each(function () { 447 var $this = $(this); 448 449 //Check we havent already initialised the plugin 450 var plugin = $this.data(PLUGIN_NS); 451 452 if (!plugin) { 453 plugin = new TouchSwipe(this, options); 454 $this.data(PLUGIN_NS, plugin); 455 } 456 }); 457 } 458 459 /** 460 * Main TouchSwipe Plugin Class. 461 * Do not use this to construct your TouchSwipe object, use the jQuery plugin method $.fn.swipe(); {@link $.fn.swipe} 462 * @private 463 * @name TouchSwipe 464 * @param {DOMNode} element The HTML DOM object to apply to plugin to 465 * @param {Object} options The options to configure the plugin with. @link {$.fn.swipe.defaults} 466 * @see $.fh.swipe.defaults 467 * @see $.fh.swipe 468 * @class 469 */ 470 function TouchSwipe(element, options) { 471 472 //take a local/instacne level copy of the options - should make it this.options really... 473 var options = $.extend({}, options); 474 475 var useTouchEvents = (SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents), 476 START_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerDown' : 'pointerdown') : 'touchstart') : 'mousedown', 477 MOVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerMove' : 'pointermove') : 'touchmove') : 'mousemove', 478 END_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerUp' : 'pointerup') : 'touchend') : 'mouseup', 479 LEAVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? 'mouseleave' : null) : 'mouseleave', //we manually detect leave on touch devices, so null event here 480 CANCEL_EV = (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerCancel' : 'pointercancel') : 'touchcancel'); 481 482 483 484 //touch properties 485 var distance = 0, 486 direction = null, 487 currentDirection = null, 488 duration = 0, 489 startTouchesDistance = 0, 490 endTouchesDistance = 0, 491 pinchZoom = 1, 492 pinchDistance = 0, 493 pinchDirection = 0, 494 maximumsMap = null; 495 496 497 498 //jQuery wrapped element for this instance 499 var $element = $(element); 500 501 //Current phase of th touch cycle 502 var phase = "start"; 503 504 // the current number of fingers being used. 505 var fingerCount = 0; 506 507 //track mouse points / delta 508 var fingerData = {}; 509 510 //track times 511 var startTime = 0, 512 endTime = 0, 513 previousTouchEndTime = 0, 514 fingerCountAtRelease = 0, 515 doubleTapStartTime = 0; 516 517 //Timeouts 518 var singleTapTimeout = null, 519 holdTimeout = null; 520 521 // Add gestures to all swipable areas if supported 522 try { 523 $element.on(START_EV, touchStart); 524 $element.on(CANCEL_EV, touchCancel); 525 } catch (e) { 526 $.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe'); 527 } 528 529 // 530 //Public methods 531 // 532 533 /** 534 * re-enables the swipe plugin with the previous configuration 535 * @function 536 * @name $.fn.swipe#enable 537 * @return {DOMNode} The Dom element that was registered with TouchSwipe 538 * @example $("#element").swipe("enable"); 539 */ 540 this.enable = function () { 541 //Incase we are already enabled, clean up... 542 this.disable(); 543 $element.on(START_EV, touchStart); 544 $element.on(CANCEL_EV, touchCancel); 545 return $element; 546 }; 547 548 /** 549 * disables the swipe plugin 550 * @function 551 * @name $.fn.swipe#disable 552 * @return {DOMNode} The Dom element that is now registered with TouchSwipe 553 * @example $("#element").swipe("disable"); 554 */ 555 this.disable = function () { 556 removeListeners(); 557 return $element; 558 }; 559 560 /** 561 * Destroy the swipe plugin completely. To use any swipe methods, you must re initialise the plugin. 562 * @function 563 * @name $.fn.swipe#destroy 564 * @example $("#element").swipe("destroy"); 565 */ 566 this.destroy = function () { 567 removeListeners(); 568 $element.data(PLUGIN_NS, null); 569 $element = null; 570 }; 571 572 573 /** 574 * Allows run time updating of the swipe configuration options. 575 * @function 576 * @name $.fn.swipe#option 577 * @param {String} property The option property to get or set, or a has of multiple options to set 578 * @param {Object} [value] The value to set the property to 579 * @return {Object} If only a property name is passed, then that property value is returned. If nothing is passed the current options hash is returned. 580 * @example $("#element").swipe("option", "threshold"); // return the threshold 581 * @example $("#element").swipe("option", "threshold", 100); // set the threshold after init 582 * @example $("#element").swipe("option", {threshold:100, fingers:3} ); // set multiple properties after init 583 * @example $("#element").swipe({threshold:100, fingers:3} ); // set multiple properties after init - the "option" method is optional! 584 * @example $("#element").swipe("option"); // Return the current options hash 585 * @see $.fn.swipe.defaults 586 * 587 */ 588 this.option = function (property, value) { 589 590 if (typeof property === 'object') { 591 options = $.extend(options, property); 592 } else if (options[property] !== undefined) { 593 if (value === undefined) { 594 return options[property]; 595 } else { 596 options[property] = value; 597 } 598 } else if (!property) { 599 return options; 600 } else { 601 $.error('Option ' + property + ' does not exist on jQuery.swipe.options'); 602 } 603 604 return null; 605 } 606 607 608 609 // 610 // Private methods 611 // 612 613 // 614 // EVENTS 615 // 616 /** 617 * Event handler for a touch start event. 618 * Stops the default click event from triggering and stores where we touched 619 * @inner 620 * @param {object} jqEvent The normalised jQuery event object. 621 */ 622 function touchStart(jqEvent) { 623 624 //If we already in a touch event (a finger already in use) then ignore subsequent ones.. 625 if (getTouchInProgress()) { 626 return; 627 } 628 629 //Check if this element matches any in the excluded elements selectors, or its parent is excluded, if so, DON'T swipe 630 if ($(jqEvent.target).closest(options.excludedElements, $element).length > 0) { 631 return; 632 } 633 634 //As we use Jquery bind for events, we need to target the original event object 635 //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one. 636 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 637 638 639 //If we have a pointer event, whoes type is 'mouse' and we have said NO mouse events, then dont do anything. 640 if (event.pointerType && event.pointerType == "mouse" && options.fallbackToMouseEvents == false) { 641 return; 642 }; 643 644 var ret, 645 touches = event.touches, 646 evt = touches ? touches[0] : event; 647 648 phase = PHASE_START; 649 650 //If we support touches, get the finger count 651 if (touches) { 652 // get the total number of fingers touching the screen 653 fingerCount = touches.length; 654 } 655 //Else this is the desktop, so stop the browser from dragging content 656 else if (options.preventDefaultEvents !== false) { 657 jqEvent.preventDefault(); //call this on jq event so we are cross browser 658 } 659 660 //clear vars.. 661 distance = 0; 662 direction = null; 663 currentDirection = null; 664 pinchDirection = null; 665 duration = 0; 666 startTouchesDistance = 0; 667 endTouchesDistance = 0; 668 pinchZoom = 1; 669 pinchDistance = 0; 670 maximumsMap = createMaximumsData(); 671 cancelMultiFingerRelease(); 672 673 //Create the default finger data 674 createFingerData(0, evt); 675 676 // check the number of fingers is what we are looking for, or we are capturing pinches 677 if (!touches || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) { 678 // get the coordinates of the touch 679 startTime = getTimeStamp(); 680 681 if (fingerCount == 2) { 682 //Keep track of the initial pinch distance, so we can calculate the diff later 683 //Store second finger data as start 684 createFingerData(1, touches[1]); 685 startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start); 686 } 687 688 if (options.swipeStatus || options.pinchStatus) { 689 ret = triggerHandler(event, phase); 690 } 691 } else { 692 //A touch with more or less than the fingers we are looking for, so cancel 693 ret = false; 694 } 695 696 //If we have a return value from the users handler, then return and cancel 697 if (ret === false) { 698 phase = PHASE_CANCEL; 699 triggerHandler(event, phase); 700 return ret; 701 } else { 702 if (options.hold) { 703 holdTimeout = setTimeout($.proxy(function () { 704 //Trigger the event 705 $element.trigger('hold', [event.target]); 706 //Fire the callback 707 if (options.hold) { 708 ret = options.hold.call($element, event, event.target); 709 } 710 }, this), options.longTapThreshold); 711 } 712 713 setTouchInProgress(true); 714 } 715 716 return null; 717 }; 718 719 720 721 /** 722 * Event handler for a touch move event. 723 * If we change fingers during move, then cancel the event 724 * @inner 725 * @param {object} jqEvent The normalised jQuery event object. 726 */ 727 function touchMove(jqEvent) { 728 729 //As we use Jquery bind for events, we need to target the original event object 730 //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one. 731 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 732 733 //If we are ending, cancelling, or within the threshold of 2 fingers being released, don't track anything.. 734 if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease()) 735 return; 736 737 var ret, 738 touches = event.touches, 739 evt = touches ? touches[0] : event; 740 741 742 //Update the finger data 743 var currentFinger = updateFingerData(evt); 744 endTime = getTimeStamp(); 745 746 if (touches) { 747 fingerCount = touches.length; 748 } 749 750 if (options.hold) { 751 clearTimeout(holdTimeout); 752 } 753 754 phase = PHASE_MOVE; 755 756 //If we have 2 fingers get Touches distance as well 757 if (fingerCount == 2) { 758 759 //Keep track of the initial pinch distance, so we can calculate the diff later 760 //We do this here as well as the start event, in case they start with 1 finger, and the press 2 fingers 761 if (startTouchesDistance == 0) { 762 //Create second finger if this is the first time... 763 createFingerData(1, touches[1]); 764 765 startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start); 766 } else { 767 //Else just update the second finger 768 updateFingerData(touches[1]); 769 770 endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end); 771 pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end); 772 } 773 774 pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance); 775 pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance); 776 } 777 778 if ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !touches || hasPinches()) { 779 780 //The overall direction of the swipe. From start to now. 781 direction = calculateDirection(currentFinger.start, currentFinger.end); 782 783 //The immediate direction of the swipe, direction between the last movement and this one. 784 currentDirection = calculateDirection(currentFinger.last, currentFinger.end); 785 786 //Check if we need to prevent default event (page scroll / pinch zoom) or not 787 validateDefaultEvent(jqEvent, currentDirection); 788 789 //Distance and duration are all off the main finger 790 distance = calculateDistance(currentFinger.start, currentFinger.end); 791 duration = calculateDuration(); 792 793 //Cache the maximum distance we made in this direction 794 setMaxDistance(direction, distance); 795 796 //Trigger status handler 797 ret = triggerHandler(event, phase); 798 799 800 //If we trigger end events when threshold are met, or trigger events when touch leaves element 801 if (!options.triggerOnTouchEnd || options.triggerOnTouchLeave) { 802 803 var inBounds = true; 804 805 //If checking if we leave the element, run the bounds check (we can use touchleave as its not supported on webkit) 806 if (options.triggerOnTouchLeave) { 807 var bounds = getbounds(this); 808 inBounds = isInBounds(currentFinger.end, bounds); 809 } 810 811 //Trigger end handles as we swipe if thresholds met or if we have left the element if the user has asked to check these.. 812 if (!options.triggerOnTouchEnd && inBounds) { 813 phase = getNextPhase(PHASE_MOVE); 814 } 815 //We end if out of bounds here, so set current phase to END, and check if its modified 816 else if (options.triggerOnTouchLeave && !inBounds) { 817 phase = getNextPhase(PHASE_END); 818 } 819 820 if (phase == PHASE_CANCEL || phase == PHASE_END) { 821 triggerHandler(event, phase); 822 } 823 } 824 } else { 825 phase = PHASE_CANCEL; 826 triggerHandler(event, phase); 827 } 828 829 if (ret === false) { 830 phase = PHASE_CANCEL; 831 triggerHandler(event, phase); 832 } 833 } 834 835 836 837 838 /** 839 * Event handler for a touch end event. 840 * Calculate the direction and trigger events 841 * @inner 842 * @param {object} jqEvent The normalised jQuery event object. 843 */ 844 function touchEnd(jqEvent) { 845 //As we use Jquery bind for events, we need to target the original event object 846 //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one. 847 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent, 848 touches = event.touches; 849 850 //If we are still in a touch with the device wait a fraction and see if the other finger comes up 851 //if it does within the threshold, then we treat it as a multi release, not a single release and end the touch / swipe 852 if (touches) { 853 if (touches.length && !inMultiFingerRelease()) { 854 startMultiFingerRelease(event); 855 return true; 856 } else if (touches.length && inMultiFingerRelease()) { 857 return true; 858 } 859 } 860 861 //If a previous finger has been released, check how long ago, if within the threshold, then assume it was a multifinger release. 862 //This is used to allow 2 fingers to release fractionally after each other, whilst maintaining the event as containing 2 fingers, not 1 863 if (inMultiFingerRelease()) { 864 fingerCount = fingerCountAtRelease; 865 } 866 867 //Set end of swipe 868 endTime = getTimeStamp(); 869 870 //Get duration incase move was never fired 871 duration = calculateDuration(); 872 873 //If we trigger handlers at end of swipe OR, we trigger during, but they didnt trigger and we are still in the move phase 874 if (didSwipeBackToCancel() || !validateSwipeDistance()) { 875 phase = PHASE_CANCEL; 876 triggerHandler(event, phase); 877 } else if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd === false && phase === PHASE_MOVE)) { 878 //call this on jq event so we are cross browser 879 if (options.preventDefaultEvents !== false && jqEvent.cancelable !== false) { 880 jqEvent.preventDefault(); 881 } 882 phase = PHASE_END; 883 triggerHandler(event, phase); 884 } 885 //Special cases - A tap should always fire on touch end regardless, 886 //So here we manually trigger the tap end handler by itself 887 //We dont run trigger handler as it will re-trigger events that may have fired already 888 else if (!options.triggerOnTouchEnd && hasTap()) { 889 //Trigger the pinch events... 890 phase = PHASE_END; 891 triggerHandlerForGesture(event, phase, TAP); 892 } else if (phase === PHASE_MOVE) { 893 phase = PHASE_CANCEL; 894 triggerHandler(event, phase); 895 } 896 897 setTouchInProgress(false); 898 899 return null; 900 } 901 902 903 904 /** 905 * Event handler for a touch cancel event. 906 * Clears current vars 907 * @inner 908 */ 909 function touchCancel() { 910 // reset the variables back to default values 911 fingerCount = 0; 912 endTime = 0; 913 startTime = 0; 914 startTouchesDistance = 0; 915 endTouchesDistance = 0; 916 pinchZoom = 1; 917 918 //If we were in progress of tracking a possible multi touch end, then re set it. 919 cancelMultiFingerRelease(); 920 921 setTouchInProgress(false); 922 } 923 924 925 /** 926 * Event handler for a touch leave event. 927 * This is only triggered on desktops, in touch we work this out manually 928 * as the touchleave event is not supported in webkit 929 * @inner 930 */ 931 function touchLeave(jqEvent) { 932 //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one. 933 var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; 934 935 //If we have the trigger on leave property set.... 936 if (options.triggerOnTouchLeave) { 937 phase = getNextPhase(PHASE_END); 938 triggerHandler(event, phase); 939 } 940 } 941 942 /** 943 * Removes all listeners that were associated with the plugin 944 * @inner 945 */ 946 function removeListeners() { 947 $element.off(START_EV, touchStart); 948 $element.off(CANCEL_EV, touchCancel); 949 $element.off(MOVE_EV, touchMove); 950 $element.off(END_EV, touchEnd); 951 952 //we only have leave events on desktop, we manually calculate leave on touch as its not supported in webkit 953 if (LEAVE_EV) { 954 $element.off(LEAVE_EV, touchLeave); 955 } 956 957 setTouchInProgress(false); 958 } 959 960 961 /** 962 * Checks if the time and distance thresholds have been met, and if so then the appropriate handlers are fired. 963 */ 964 function getNextPhase(currentPhase) { 965 966 var nextPhase = currentPhase; 967 968 // Ensure we have valid swipe (under time and over distance and check if we are out of bound...) 969 var validTime = validateSwipeTime(); 970 var validDistance = validateSwipeDistance(); 971 var didCancel = didSwipeBackToCancel(); 972 973 //If we have exceeded our time, then cancel 974 if (!validTime || didCancel) { 975 nextPhase = PHASE_CANCEL; 976 } 977 //Else if we are moving, and have reached distance then end 978 else if (validDistance && currentPhase == PHASE_MOVE && (!options.triggerOnTouchEnd || options.triggerOnTouchLeave)) { 979 nextPhase = PHASE_END; 980 } 981 //Else if we have ended by leaving and didn't reach distance, then cancel 982 else if (!validDistance && currentPhase == PHASE_END && options.triggerOnTouchLeave) { 983 nextPhase = PHASE_CANCEL; 984 } 985 986 return nextPhase; 987 } 988 989 990 /** 991 * Trigger the relevant event handler 992 * 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" 993 * @param {object} event the original event object 994 * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases} 995 * @inner 996 */ 997 function triggerHandler(event, phase) { 998 999 1000 1001 var ret, 1002 touches = event.touches; 1003 1004 // SWIPE GESTURES 1005 if (didSwipe() || hasSwipes()) { 1006 ret = triggerHandlerForGesture(event, phase, SWIPE); 1007 } 1008 1009 // PINCH GESTURES (if the above didn't cancel) 1010 if ((didPinch() || hasPinches()) && ret !== false) { 1011 ret = triggerHandlerForGesture(event, phase, PINCH); 1012 } 1013 1014 // CLICK / TAP (if the above didn't cancel) 1015 if (didDoubleTap() && ret !== false) { 1016 //Trigger the tap events... 1017 ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP); 1018 } 1019 1020 // CLICK / TAP (if the above didn't cancel) 1021 else if (didLongTap() && ret !== false) { 1022 //Trigger the tap events... 1023 ret = triggerHandlerForGesture(event, phase, LONG_TAP); 1024 } 1025 1026 // CLICK / TAP (if the above didn't cancel) 1027 else if (didTap() && ret !== false) { 1028 //Trigger the tap event.. 1029 ret = triggerHandlerForGesture(event, phase, TAP); 1030 } 1031 1032 1033 1034 // If we are cancelling the gesture, then manually trigger the reset handler 1035 if (phase === PHASE_CANCEL) { 1036 1037 touchCancel(event); 1038 } 1039 1040 1041 1042 1043 // If we are ending the gesture, then manually trigger the reset handler IF all fingers are off 1044 if (phase === PHASE_END) { 1045 //If we support touch, then check that all fingers are off before we cancel 1046 if (touches) { 1047 if (!touches.length) { 1048 touchCancel(event); 1049 } 1050 } else { 1051 touchCancel(event); 1052 } 1053 } 1054 1055 return ret; 1056 } 1057 1058 1059 1060 /** 1061 * Trigger the relevant event handler 1062 * 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" 1063 * @param {object} event the original event object 1064 * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases} 1065 * @param {string} gesture the gesture to trigger a handler for : PINCH or SWIPE {@link $.fn.swipe.gestures} 1066 * @return Boolean False, to indicate that the event should stop propagation, or void. 1067 * @inner 1068 */ 1069 function triggerHandlerForGesture(event, phase, gesture) { 1070 1071 var ret; 1072 1073 //SWIPES.... 1074 if (gesture == SWIPE) { 1075 //Trigger status every time.. 1076 $element.trigger('swipeStatus', [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData, currentDirection]); 1077 1078 if (options.swipeStatus) { 1079 ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData, currentDirection); 1080 //If the status cancels, then dont run the subsequent event handlers.. 1081 if (ret === false) return false; 1082 } 1083 1084 if (phase == PHASE_END && validateSwipe()) { 1085 1086 //Cancel any taps that were in progress... 1087 clearTimeout(singleTapTimeout); 1088 clearTimeout(holdTimeout); 1089 1090 $element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData, currentDirection]); 1091 1092 if (options.swipe) { 1093 ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData, currentDirection); 1094 //If the status cancels, then dont run the subsequent event handlers.. 1095 if (ret === false) return false; 1096 } 1097 1098 //trigger direction specific event handlers 1099 switch (direction) { 1100 case LEFT: 1101 $element.trigger('swipeLeft', [direction, distance, duration, fingerCount, fingerData, currentDirection]); 1102 1103 if (options.swipeLeft) { 1104 ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount, fingerData, currentDirection); 1105 } 1106 break; 1107 1108 case RIGHT: 1109 $element.trigger('swipeRight', [direction, distance, duration, fingerCount, fingerData, currentDirection]); 1110 1111 if (options.swipeRight) { 1112 ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount, fingerData, currentDirection); 1113 } 1114 break; 1115 1116 case UP: 1117 $element.trigger('swipeUp', [direction, distance, duration, fingerCount, fingerData, currentDirection]); 1118 1119 if (options.swipeUp) { 1120 ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount, fingerData, currentDirection); 1121 } 1122 break; 1123 1124 case DOWN: 1125 $element.trigger('swipeDown', [direction, distance, duration, fingerCount, fingerData, currentDirection]); 1126 1127 if (options.swipeDown) { 1128 ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount, fingerData, currentDirection); 1129 } 1130 break; 1131 } 1132 } 1133 } 1134 1135 1136 //PINCHES.... 1137 if (gesture == PINCH) { 1138 $element.trigger('pinchStatus', [phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); 1139 1140 if (options.pinchStatus) { 1141 ret = options.pinchStatus.call($element, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); 1142 //If the status cancels, then dont run the subsequent event handlers.. 1143 if (ret === false) return false; 1144 } 1145 1146 if (phase == PHASE_END && validatePinch()) { 1147 1148 switch (pinchDirection) { 1149 case IN: 1150 $element.trigger('pinchIn', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); 1151 1152 if (options.pinchIn) { 1153 ret = options.pinchIn.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); 1154 } 1155 break; 1156 1157 case OUT: 1158 $element.trigger('pinchOut', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); 1159 1160 if (options.pinchOut) { 1161 ret = options.pinchOut.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); 1162 } 1163 break; 1164 } 1165 } 1166 } 1167 1168 if (gesture == TAP) { 1169 if (phase === PHASE_CANCEL || phase === PHASE_END) { 1170 1171 clearTimeout(singleTapTimeout); 1172 clearTimeout(holdTimeout); 1173 1174 //If we are also looking for doubelTaps, wait incase this is one... 1175 if (hasDoubleTap() && !inDoubleTap()) { 1176 doubleTapStartTime = getTimeStamp(); 1177 1178 //Now wait for the double tap timeout, and trigger this single tap 1179 //if its not cancelled by a double tap 1180 singleTapTimeout = setTimeout($.proxy(function () { 1181 doubleTapStartTime = null; 1182 $element.trigger('tap', [event.target]); 1183 1184 if (options.tap) { 1185 ret = options.tap.call($element, event, event.target); 1186 } 1187 }, this), options.doubleTapThreshold); 1188 1189 } else { 1190 doubleTapStartTime = null; 1191 $element.trigger('tap', [event.target]); 1192 if (options.tap) { 1193 ret = options.tap.call($element, event, event.target); 1194 } 1195 } 1196 } 1197 } else if (gesture == DOUBLE_TAP) { 1198 if (phase === PHASE_CANCEL || phase === PHASE_END) { 1199 clearTimeout(singleTapTimeout); 1200 clearTimeout(holdTimeout); 1201 doubleTapStartTime = null; 1202 $element.trigger('doubletap', [event.target]); 1203 1204 if (options.doubleTap) { 1205 ret = options.doubleTap.call($element, event, event.target); 1206 } 1207 } 1208 } else if (gesture == LONG_TAP) { 1209 if (phase === PHASE_CANCEL || phase === PHASE_END) { 1210 clearTimeout(singleTapTimeout); 1211 doubleTapStartTime = null; 1212 1213 $element.trigger('longtap', [event.target]); 1214 if (options.longTap) { 1215 ret = options.longTap.call($element, event, event.target); 1216 } 1217 } 1218 } 1219 1220 return ret; 1221 } 1222 1223 1224 // 1225 // GESTURE VALIDATION 1226 // 1227 1228 /** 1229 * Checks the user has swipe far enough 1230 * @return Boolean if <code>threshold</code> has been set, return true if the threshold was met, else false. 1231 * If no threshold was set, then we return true. 1232 * @inner 1233 */ 1234 function validateSwipeDistance() { 1235 var valid = true; 1236 //If we made it past the min swipe distance.. 1237 if (options.threshold !== null) { 1238 valid = distance >= options.threshold; 1239 } 1240 1241 return valid; 1242 } 1243 1244 /** 1245 * Checks the user has swiped back to cancel. 1246 * @return Boolean if <code>cancelThreshold</code> has been set, return true if the cancelThreshold was met, else false. 1247 * If no cancelThreshold was set, then we return true. 1248 * @inner 1249 */ 1250 function didSwipeBackToCancel() { 1251 var cancelled = false; 1252 if (options.cancelThreshold !== null && direction !== null) { 1253 cancelled = (getMaxDistance(direction) - distance) >= options.cancelThreshold; 1254 } 1255 1256 return cancelled; 1257 } 1258 1259 /** 1260 * Checks the user has pinched far enough 1261 * @return Boolean if <code>pinchThreshold</code> has been set, return true if the threshold was met, else false. 1262 * If no threshold was set, then we return true. 1263 * @inner 1264 */ 1265 function validatePinchDistance() { 1266 if (options.pinchThreshold !== null) { 1267 return pinchDistance >= options.pinchThreshold; 1268 } 1269 return true; 1270 } 1271 1272 /** 1273 * Checks that the time taken to swipe meets the minimum / maximum requirements 1274 * @return Boolean 1275 * @inner 1276 */ 1277 function validateSwipeTime() { 1278 var result; 1279 //If no time set, then return true 1280 if (options.maxTimeThreshold) { 1281 if (duration >= options.maxTimeThreshold) { 1282 result = false; 1283 } else { 1284 result = true; 1285 } 1286 } else { 1287 result = true; 1288 } 1289 1290 return result; 1291 } 1292 1293 1294 /** 1295 * Checks direction of the swipe and the value allowPageScroll to see if we should allow or prevent the default behaviour from occurring. 1296 * This will essentially allow page scrolling or not when the user is swiping on a touchSwipe object. 1297 * @param {object} jqEvent The normalised jQuery representation of the event object. 1298 * @param {string} direction The direction of the event. See {@link $.fn.swipe.directions} 1299 * @see $.fn.swipe.directions 1300 * @inner 1301 */ 1302 function validateDefaultEvent(jqEvent, direction) { 1303 1304 //If the option is set, allways allow the event to bubble up (let user handle weirdness) 1305 if (options.preventDefaultEvents === false) { 1306 return; 1307 } 1308 1309 if (options.allowPageScroll === NONE) { 1310 jqEvent.preventDefault(); 1311 } else { 1312 var auto = options.allowPageScroll === AUTO; 1313 1314 switch (direction) { 1315 case LEFT: 1316 if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) { 1317 jqEvent.preventDefault(); 1318 } 1319 break; 1320 1321 case RIGHT: 1322 if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) { 1323 jqEvent.preventDefault(); 1324 } 1325 break; 1326 1327 case UP: 1328 if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) { 1329 jqEvent.preventDefault(); 1330 } 1331 break; 1332 1333 case DOWN: 1334 if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) { 1335 jqEvent.preventDefault(); 1336 } 1337 break; 1338 1339 case NONE: 1340 1341 break; 1342 } 1343 } 1344 } 1345 1346 1347 // PINCHES 1348 /** 1349 * Returns true of the current pinch meets the thresholds 1350 * @return Boolean 1351 * @inner 1352 */ 1353 function validatePinch() { 1354 var hasCorrectFingerCount = validateFingers(); 1355 var hasEndPoint = validateEndPoint(); 1356 var hasCorrectDistance = validatePinchDistance(); 1357 return hasCorrectFingerCount && hasEndPoint && hasCorrectDistance; 1358 1359 } 1360 1361 /** 1362 * Returns true if any Pinch events have been registered 1363 * @return Boolean 1364 * @inner 1365 */ 1366 function hasPinches() { 1367 //Enure we dont return 0 or null for false values 1368 return !!(options.pinchStatus || options.pinchIn || options.pinchOut); 1369 } 1370 1371 /** 1372 * Returns true if we are detecting pinches, and have one 1373 * @return Boolean 1374 * @inner 1375 */ 1376 function didPinch() { 1377 //Enure we dont return 0 or null for false values 1378 return !!(validatePinch() && hasPinches()); 1379 } 1380 1381 1382 1383 1384 // SWIPES 1385 /** 1386 * Returns true if the current swipe meets the thresholds 1387 * @return Boolean 1388 * @inner 1389 */ 1390 function validateSwipe() { 1391 //Check validity of swipe 1392 var hasValidTime = validateSwipeTime(); 1393 var hasValidDistance = validateSwipeDistance(); 1394 var hasCorrectFingerCount = validateFingers(); 1395 var hasEndPoint = validateEndPoint(); 1396 var didCancel = didSwipeBackToCancel(); 1397 1398 // if the user swiped more than the minimum length, perform the appropriate action 1399 // hasValidDistance is null when no distance is set 1400 var valid = !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime; 1401 1402 return valid; 1403 } 1404 1405 /** 1406 * Returns true if any Swipe events have been registered 1407 * @return Boolean 1408 * @inner 1409 */ 1410 function hasSwipes() { 1411 //Enure we dont return 0 or null for false values 1412 return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown); 1413 } 1414 1415 1416 /** 1417 * Returns true if we are detecting swipes and have one 1418 * @return Boolean 1419 * @inner 1420 */ 1421 function didSwipe() { 1422 //Enure we dont return 0 or null for false values 1423 return !!(validateSwipe() && hasSwipes()); 1424 } 1425 1426 /** 1427 * Returns true if we have matched the number of fingers we are looking for 1428 * @return Boolean 1429 * @inner 1430 */ 1431 function validateFingers() { 1432 //The number of fingers we want were matched, or on desktop we ignore 1433 return ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH); 1434 } 1435 1436 /** 1437 * Returns true if we have an end point for the swipe 1438 * @return Boolean 1439 * @inner 1440 */ 1441 function validateEndPoint() { 1442 //We have an end value for the finger 1443 return fingerData[0].end.x !== 0; 1444 } 1445 1446 // TAP / CLICK 1447 /** 1448 * Returns true if a click / tap events have been registered 1449 * @return Boolean 1450 * @inner 1451 */ 1452 function hasTap() { 1453 //Enure we dont return 0 or null for false values 1454 return !!(options.tap); 1455 } 1456 1457 /** 1458 * Returns true if a double tap events have been registered 1459 * @return Boolean 1460 * @inner 1461 */ 1462 function hasDoubleTap() { 1463 //Enure we dont return 0 or null for false values 1464 return !!(options.doubleTap); 1465 } 1466 1467 /** 1468 * Returns true if any long tap events have been registered 1469 * @return Boolean 1470 * @inner 1471 */ 1472 function hasLongTap() { 1473 //Enure we dont return 0 or null for false values 1474 return !!(options.longTap); 1475 } 1476 1477 /** 1478 * 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. 1479 * @return Boolean 1480 * @inner 1481 */ 1482 function validateDoubleTap() { 1483 if (doubleTapStartTime == null) { 1484 return false; 1485 } 1486 var now = getTimeStamp(); 1487 return (hasDoubleTap() && ((now - doubleTapStartTime) <= options.doubleTapThreshold)); 1488 } 1489 1490 /** 1491 * 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. 1492 * @return Boolean 1493 * @inner 1494 */ 1495 function inDoubleTap() { 1496 return validateDoubleTap(); 1497 } 1498 1499 1500 /** 1501 * Returns true if we have a valid tap 1502 * @return Boolean 1503 * @inner 1504 */ 1505 function validateTap() { 1506 return ((fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold)); 1507 } 1508 1509 /** 1510 * Returns true if we have a valid long tap 1511 * @return Boolean 1512 * @inner 1513 */ 1514 function validateLongTap() { 1515 //slight threshold on moving finger 1516 return ((duration > options.longTapThreshold) && (distance < DOUBLE_TAP_THRESHOLD)); 1517 } 1518 1519 /** 1520 * Returns true if we are detecting taps and have one 1521 * @return Boolean 1522 * @inner 1523 */ 1524 function didTap() { 1525 //Enure we dont return 0 or null for false values 1526 return !!(validateTap() && hasTap()); 1527 } 1528 1529 1530 /** 1531 * Returns true if we are detecting double taps and have one 1532 * @return Boolean 1533 * @inner 1534 */ 1535 function didDoubleTap() { 1536 //Enure we dont return 0 or null for false values 1537 return !!(validateDoubleTap() && hasDoubleTap()); 1538 } 1539 1540 /** 1541 * Returns true if we are detecting long taps and have one 1542 * @return Boolean 1543 * @inner 1544 */ 1545 function didLongTap() { 1546 //Enure we dont return 0 or null for false values 1547 return !!(validateLongTap() && hasLongTap()); 1548 } 1549 1550 1551 1552 1553 // MULTI FINGER TOUCH 1554 /** 1555 * Starts tracking the time between 2 finger releases, and keeps track of how many fingers we initially had up 1556 * @inner 1557 */ 1558 function startMultiFingerRelease(event) { 1559 previousTouchEndTime = getTimeStamp(); 1560 fingerCountAtRelease = event.touches.length + 1; 1561 } 1562 1563 /** 1564 * Cancels the tracking of time between 2 finger releases, and resets counters 1565 * @inner 1566 */ 1567 function cancelMultiFingerRelease() { 1568 previousTouchEndTime = 0; 1569 fingerCountAtRelease = 0; 1570 } 1571 1572 /** 1573 * Checks if we are in the threshold between 2 fingers being released 1574 * @return Boolean 1575 * @inner 1576 */ 1577 function inMultiFingerRelease() { 1578 1579 var withinThreshold = false; 1580 1581 if (previousTouchEndTime) { 1582 var diff = getTimeStamp() - previousTouchEndTime 1583 if (diff <= options.fingerReleaseThreshold) { 1584 withinThreshold = true; 1585 } 1586 } 1587 1588 return withinThreshold; 1589 } 1590 1591 1592 /** 1593 * gets a data flag to indicate that a touch is in progress 1594 * @return Boolean 1595 * @inner 1596 */ 1597 function getTouchInProgress() { 1598 //strict equality to ensure only true and false are returned 1599 return !!($element.data(PLUGIN_NS + '_intouch') === true); 1600 } 1601 1602 /** 1603 * Sets a data flag to indicate that a touch is in progress 1604 * @param {boolean} val The value to set the property to 1605 * @inner 1606 */ 1607 function setTouchInProgress(val) { 1608 1609 //If destroy is called in an event handler, we have no el, and we have already cleaned up, so return. 1610 if (!$element) { 1611 return; 1612 } 1613 1614 //Add or remove event listeners depending on touch status 1615 if (val === true) { 1616 $element.on(MOVE_EV, touchMove); 1617 $element.on(END_EV, touchEnd); 1618 1619 //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit 1620 if (LEAVE_EV) { 1621 $element.on(LEAVE_EV, touchLeave); 1622 } 1623 } else { 1624 1625 $element.off(MOVE_EV, touchMove, false); 1626 $element.off(END_EV, touchEnd, false); 1627 1628 //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit 1629 if (LEAVE_EV) { 1630 $element.off(LEAVE_EV, touchLeave, false); 1631 } 1632 } 1633 1634 1635 //strict equality to ensure only true and false can update the value 1636 $element.data(PLUGIN_NS + '_intouch', val === true); 1637 } 1638 1639 1640 /** 1641 * Creates the finger data for the touch/finger in the event object. 1642 * @param {int} id The id to store the finger data under (usually the order the fingers were pressed) 1643 * @param {object} evt The event object containing finger data 1644 * @return finger data object 1645 * @inner 1646 */ 1647 function createFingerData(id, evt) { 1648 var f = { 1649 start: { 1650 x: 0, 1651 y: 0 1652 }, 1653 last: { 1654 x: 0, 1655 y: 0 1656 }, 1657 end: { 1658 x: 0, 1659 y: 0 1660 } 1661 }; 1662 f.start.x = f.last.x = f.end.x = evt.pageX || evt.clientX; 1663 f.start.y = f.last.y = f.end.y = evt.pageY || evt.clientY; 1664 fingerData[id] = f; 1665 return f; 1666 } 1667 1668 /** 1669 * Updates the finger data for a particular event object 1670 * @param {object} evt The event object containing the touch/finger data to upadte 1671 * @return a finger data object. 1672 * @inner 1673 */ 1674 function updateFingerData(evt) { 1675 var id = evt.identifier !== undefined ? evt.identifier : 0; 1676 var f = getFingerData(id); 1677 1678 if (f === null) { 1679 f = createFingerData(id, evt); 1680 } 1681 1682 f.last.x = f.end.x; 1683 f.last.y = f.end.y; 1684 1685 f.end.x = evt.pageX || evt.clientX; 1686 f.end.y = evt.pageY || evt.clientY; 1687 1688 return f; 1689 } 1690 1691 /** 1692 * Returns a finger data object by its event ID. 1693 * Each touch event has an identifier property, which is used 1694 * to track repeat touches 1695 * @param {int} id The unique id of the finger in the sequence of touch events. 1696 * @return a finger data object. 1697 * @inner 1698 */ 1699 function getFingerData(id) { 1700 return fingerData[id] || null; 1701 } 1702 1703 1704 /** 1705 * Sets the maximum distance swiped in the given direction. 1706 * If the new value is lower than the current value, the max value is not changed. 1707 * @param {string} direction The direction of the swipe 1708 * @param {int} distance The distance of the swipe 1709 * @inner 1710 */ 1711 function setMaxDistance(direction, distance) { 1712 if (direction == NONE) return; 1713 distance = Math.max(distance, getMaxDistance(direction)); 1714 maximumsMap[direction].distance = distance; 1715 } 1716 1717 /** 1718 * gets the maximum distance swiped in the given direction. 1719 * @param {string} direction The direction of the swipe 1720 * @return int The distance of the swipe 1721 * @inner 1722 */ 1723 function getMaxDistance(direction) { 1724 if (maximumsMap[direction]) return maximumsMap[direction].distance; 1725 return undefined; 1726 } 1727 1728 /** 1729 * Creats a map of directions to maximum swiped values. 1730 * @return Object A dictionary of maximum values, indexed by direction. 1731 * @inner 1732 */ 1733 function createMaximumsData() { 1734 var maxData = {}; 1735 maxData[LEFT] = createMaximumVO(LEFT); 1736 maxData[RIGHT] = createMaximumVO(RIGHT); 1737 maxData[UP] = createMaximumVO(UP); 1738 maxData[DOWN] = createMaximumVO(DOWN); 1739 1740 return maxData; 1741 } 1742 1743 /** 1744 * Creates a map maximum swiped values for a given swipe direction 1745 * @param {string} The direction that these values will be associated with 1746 * @return Object Maximum values 1747 * @inner 1748 */ 1749 function createMaximumVO(dir) { 1750 return { 1751 direction: dir, 1752 distance: 0 1753 } 1754 } 1755 1756 1757 // 1758 // MATHS / UTILS 1759 // 1760 1761 /** 1762 * Calculate the duration of the swipe 1763 * @return int 1764 * @inner 1765 */ 1766 function calculateDuration() { 1767 return endTime - startTime; 1768 } 1769 1770 /** 1771 * Calculate the distance between 2 touches (pinch) 1772 * @param {point} startPoint A point object containing x and y co-ordinates 1773 * @param {point} endPoint A point object containing x and y co-ordinates 1774 * @return int; 1775 * @inner 1776 */ 1777 function calculateTouchesDistance(startPoint, endPoint) { 1778 var diffX = Math.abs(startPoint.x - endPoint.x); 1779 var diffY = Math.abs(startPoint.y - endPoint.y); 1780 1781 return Math.round(Math.sqrt(diffX * diffX + diffY * diffY)); 1782 } 1783 1784 /** 1785 * Calculate the zoom factor between the start and end distances 1786 * @param {int} startDistance Distance (between 2 fingers) the user started pinching at 1787 * @param {int} endDistance Distance (between 2 fingers) the user ended pinching at 1788 * @return float The zoom value from 0 to 1. 1789 * @inner 1790 */ 1791 function calculatePinchZoom(startDistance, endDistance) { 1792 var percent = (endDistance / startDistance) * 1; 1793 return percent.toFixed(2); 1794 } 1795 1796 1797 /** 1798 * Returns the pinch direction, either IN or OUT for the given points 1799 * @return string Either {@link $.fn.swipe.directions.IN} or {@link $.fn.swipe.directions.OUT} 1800 * @see $.fn.swipe.directions 1801 * @inner 1802 */ 1803 function calculatePinchDirection() { 1804 if (pinchZoom < 1) { 1805 return OUT; 1806 } else { 1807 return IN; 1808 } 1809 } 1810 1811 1812 /** 1813 * Calculate the length / distance of the swipe 1814 * @param {point} startPoint A point object containing x and y co-ordinates 1815 * @param {point} endPoint A point object containing x and y co-ordinates 1816 * @return int 1817 * @inner 1818 */ 1819 function calculateDistance(startPoint, endPoint) { 1820 return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2))); 1821 } 1822 1823 /** 1824 * Calculate the angle of the swipe 1825 * @param {point} startPoint A point object containing x and y co-ordinates 1826 * @param {point} endPoint A point object containing x and y co-ordinates 1827 * @return int 1828 * @inner 1829 */ 1830 function calculateAngle(startPoint, endPoint) { 1831 var x = startPoint.x - endPoint.x; 1832 var y = endPoint.y - startPoint.y; 1833 var r = Math.atan2(y, x); //radians 1834 var angle = Math.round(r * 180 / Math.PI); //degrees 1835 1836 //ensure value is positive 1837 if (angle < 0) { 1838 angle = 360 - Math.abs(angle); 1839 } 1840 1841 return angle; 1842 } 1843 1844 /** 1845 * Calculate the direction of the swipe 1846 * This will also call calculateAngle to get the latest angle of swipe 1847 * @param {point} startPoint A point object containing x and y co-ordinates 1848 * @param {point} endPoint A point object containing x and y co-ordinates 1849 * @return string Either {@link $.fn.swipe.directions.LEFT} / {@link $.fn.swipe.directions.RIGHT} / {@link $.fn.swipe.directions.DOWN} / {@link $.fn.swipe.directions.UP} 1850 * @see $.fn.swipe.directions 1851 * @inner 1852 */ 1853 function calculateDirection(startPoint, endPoint) { 1854 1855 if (comparePoints(startPoint, endPoint)) { 1856 return NONE; 1857 } 1858 1859 var angle = calculateAngle(startPoint, endPoint); 1860 1861 if ((angle <= 45) && (angle >= 0)) { 1862 return LEFT; 1863 } else if ((angle <= 360) && (angle >= 315)) { 1864 return LEFT; 1865 } else if ((angle >= 135) && (angle <= 225)) { 1866 return RIGHT; 1867 } else if ((angle > 45) && (angle < 135)) { 1868 return DOWN; 1869 } else { 1870 return UP; 1871 } 1872 } 1873 1874 1875 /** 1876 * Returns a MS time stamp of the current time 1877 * @return int 1878 * @inner 1879 */ 1880 function getTimeStamp() { 1881 var now = new Date(); 1882 return now.getTime(); 1883 } 1884 1885 1886 1887 /** 1888 * Returns a bounds object with left, right, top and bottom properties for the element specified. 1889 * @param {DomNode} The DOM node to get the bounds for. 1890 */ 1891 function getbounds(el) { 1892 el = $(el); 1893 var offset = el.offset(); 1894 1895 var bounds = { 1896 left: offset.left, 1897 right: offset.left + el.outerWidth(), 1898 top: offset.top, 1899 bottom: offset.top + el.outerHeight() 1900 } 1901 1902 return bounds; 1903 } 1904 1905 1906 /** 1907 * Checks if the point object is in the bounds object. 1908 * @param {object} point A point object. 1909 * @param {int} point.x The x value of the point. 1910 * @param {int} point.y The x value of the point. 1911 * @param {object} bounds The bounds object to test 1912 * @param {int}
1912 bounds.left The leftmost value 1913 * @param {int} bounds.right The righttmost value 1914 * @param {int} bounds.top The topmost value 1915 * @param {int} bounds.bottom The bottommost value 1916 */ 1917 function isInBounds(point, bounds) { 1918 return (point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom); 1919 }; 1920 1921 /** 1922 * Checks if the two points are equal 1923 * @param {object} point A point object. 1924 * @param {object} point B point object. 1925 * @return true of the points match 1926 */ 1927 function comparePoints(pointA, pointB) { 1928 return (pointA.x == pointB.x && pointA.y == pointB.y); 1929 } 1930 1931 1932 } 1933 1934 1935 1936 1937 /** 1938 * A catch all handler that is triggered for all swipe directions. 1939 * @name $.fn.swipe#swipe 1940 * @event 1941 * @default null 1942 * @param {EventObject} event The original event object 1943 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 1944 * @param {int} distance The distance the user swiped 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 {object} fingerData The coordinates of fingers in event 1948 * @param {string} currentDirection The current direction the user is swiping. 1949 */ 1950 1951 1952 1953 1954 /** 1955 * A handler that is triggered for "left" swipes. 1956 * @name $.fn.swipe#swipeLeft 1957 * @event 1958 * @default null 1959 * @param {EventObject} event The original event object 1960 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 1961 * @param {int} distance The distance the user swiped 1962 * @param {int} duration The duration of the swipe in milliseconds 1963 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1964 * @param {object} fingerData The coordinates of fingers in event 1965 * @param {string} currentDirection The current direction the user is swiping. 1966 */ 1967 1968 /** 1969 * A handler that is triggered for "right" swipes. 1970 * @name $.fn.swipe#swipeRight 1971 * @event 1972 * @default null 1973 * @param {EventObject} event The original event object 1974 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 1975 * @param {int} distance The distance the user swiped 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 * @param {string} currentDirection The current direction the user is swiping. 1980 */ 1981 1982 /** 1983 * A handler that is triggered for "up" swipes. 1984 * @name $.fn.swipe#swipeUp 1985 * @event 1986 * @default null 1987 * @param {EventObject} event The original event object 1988 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 1989 * @param {int} distance The distance the user swiped 1990 * @param {int} duration The duration of the swipe in milliseconds 1991 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 1992 * @param {object} fingerData The coordinates of fingers in event 1993 * @param {string} currentDirection The current direction the user is swiping. 1994 */ 1995 1996 /** 1997 * A handler that is triggered for "down" swipes. 1998 * @name $.fn.swipe#swipeDown 1999 * @event 2000 * @default null 2001 * @param {EventObject} event The original event object 2002 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} 2003 * @param {int} distance The distance the user swiped 2004 * @param {int} duration The duration of the swipe in milliseconds 2005 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 2006 * @param {object} fingerData The coordinates of fingers in event 2007 * @param {string} currentDirection The current direction the user is swiping. 2008 */ 2009 2010 /** 2011 * A handler triggered for every phase of the swipe. This handler is constantly f
2011ired for the duration of the pinch. 2012 * This is triggered regardless of swipe thresholds. 2013 * @name $.fn.swipe#swipeStatus 2014 * @event 2015 * @default null 2016 * @param {EventObject} event The original event object 2017 * @param {string} phase The phase of the swipe event. See {@link $.fn.swipe.phases} 2018 * @param {string} direction The direction the user swiped in. This is null if the user has yet to move. See {@link $.fn.swipe.directions} 2019 * @param {int} distance The distance the user swiped. This is 0 if the user has yet to move. 2020 * @param {int} duration The duration of the swipe in milliseconds 2021 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 2022 * @param {object} fingerData The coordinates of fingers in event 2023 * @param {string} currentDirection The current direction the user is swiping. 2024 */ 2025 2026 /** 2027 * A handler triggered for pinch in events. 2028 * @name $.fn.swipe#pinchIn 2029 * @event 2030 * @default null 2031 * @param {EventObject} event The original event object 2032 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions} 2033 * @param {int} distance The distance the user pinched 2034 * @param {int} duration The duration of the swipe in milliseconds 2035 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 2036 * @param {int} zoom The zoom/scale level the user pinched too, 0-1. 2037 * @param {object} fingerData The coordinates of fingers in event 2038 */ 2039 2040 /** 2041 * A handler triggered for pinch out events. 2042 * @name $.fn.swipe#pinchOut 2043 * @event 2044 * @default null 2045 * @param {EventObject} event The original event object 2046 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions} 2047 * @param {int} distance The distance the user pinched 2048 * @param {int} duration The duration of the swipe in milliseconds 2049 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 2050 * @param {int} zoom The zoom/scale level the user pinched too, 0-1. 2051 * @param {object} fingerData The coordinates of fingers in event 2052 */ 2053 2054 /** 2055 * A handler triggered for all pinch events. This handler is constantly fired for the duration of the pinch. This is triggered regardless of thresholds. 2056 * @name $.fn.swipe#pinchStatus 2057 * @event 2058 * @default null 2059 * @param {EventObject} event The original event object 2060 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions} 2061 * @param {int} distance The distance the user pinched 2062 * @param {int} duration The duration of the swipe in milliseconds 2063 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} 2064 * @param {int} zoom The zoom/scale level the user pinched too, 0-1. 2065 * @param {object} fingerData The coordinates of fingers in event 2066 */ 2067 2068 /** 2069 * A click handler triggered when a user simply clicks, rather than swipes on an element. 2070 * This is deprecated since version 1.6.2, any assignment to click will be assigned to the tap handler. 2071 * You cannot use <code>on</code> to bind to this event as the default jQ <code>click</code> event will be triggered. 2072 * Use the <code>tap</code> event instead. 2073 * @name $.fn.swipe#click 2074 * @event 2075 * @deprecated since version 1.6.2, please use {@link $.fn.swipe#tap} instead 2076 * @default null 2077 * @param {EventObject} event The original event object 2078 * @param {DomObject} target The element clicked on. 2079 */ 2080 2081 /** 2082 * A click / tap handler triggered when a user simply clicks or taps, rather than swipes on an element. 2083 * @name $.fn.swipe#tap 2084 * @event 2085 * @default null 2086 * @param {EventObject} event The original event object 2087 * @param {DomObject} target The element clicked on. 2088 */ 2089 2090 /** 2091 * A double tap handler triggered when a user double clicks or taps on an element. 2092 * You can set the time delay for a double tap with the {@link $.fn.swipe.defaults#doubleTapThreshold} property. 2093 * 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> 2094 * as the script needs to check if its a double tap. 2095 * @name $.fn.swipe#doubleTap 2096 * @see $.fn.swipe.defaults#doubleTapThreshold 2097 * @event 2098 * @default null 2099 * @param {EventObject} event The original event object 2100 * @param {DomObject} target The element clicked on. 2101 */ 2102 2103 /** 2104 * A long tap handler triggered once a tap has been release if the tap was longer than the longTapThreshold. 2105 * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. 2106 * @name $.fn.swipe#longTap 2107 * @see $.fn.swipe.defaults#longTapThreshold 2108 * @event 2109 * @default null 2110 * @param {EventObject} event The original event object 2111 * @param {DomObject} target The element clicked on. 2112 */ 2113 2114 /** 2115 * A hold tap handler triggered as soon as the longTapThreshold is reached 2116 * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. 2117 * @name $.fn.swipe#hold 2118 * @see $.fn.swipe.defaults#longTapThreshold 2119 * @event 2120 * @default null 2121 * @param {EventObject} event The original event object 2122 * @param {DomObject} target The element clicked on. 2123 */ 2124 2125})); 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145String.prototype.replaceAll = function (target, replacement) { 2146 return this.split(target).join(replacement); 2147}; 2148 2149 2150 2151 2152 2153 2154
2155if (settings_ankerpunkte) { 2156 jQuery(document).ready(function () { 2157 /* zum Inhalt scrollen */ 2158 if (window.location.href.indexOf("#") == -1) { 2159 var target = jQuery('#main'); 2160 if (!(jQuery('body').hasClass('page-home')) && target.length) { 2161 if (!getQueryStringParameter || getQueryStringParameter('filter') == null) { 2162 jQuery('html, body').delay(10).animate({ 2163 scrollTop: target.offset().top -100 2164 }, 1000); 2165 return false; 2166 }; 2167 }; 2168 }; 2169 }); 2170}; 2171 2172var getQueryStringParameter = function (token) { 2173 var params = new URLSearchParams(location.search); 2174 var value = params.get(token); 2175 if (value == null) return null; 2176 return decodeURIComponent(value); 2177}; 2178 2179var setQueryStringParameter = function (token, value) { 2180 const regExp = new RegExp(param + "(.+?)(&|$)", "g"); 2181 const newUrl = window.location.href.replace(regExp, param + "=" + value + "$2"); 2182 window.history.pushState('', '', newUrl); 2183}; 2184 2185var encodeQueryData = function (data) { 2186 const ret = []; 2187 for (let d in data) 2188 ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d])); 2189 return ret.join('&'); 2190} 2191 2192jQuery(document).ready(function () { 2193 setQueryStringParameter = function (token, value) { 2194 var params = new URLSearchParams(location.search); 2195 params.set(token, encodeURIComponent(value)); 2196 if (value == null) { 2197 if (params.delete) params.delete(token); 2198 else token = ''; 2199 }; 2200 2201 var ps = params.toString(); 2202 if (ps == '') window.history.replaceState({}, "", location.pathname); 2203 else window.history.replaceState({}, "", location.pathname + '?' + ps); 2204 }; 2205}); 2206 2207jQuery(document).ready(function () { 2208 jQuery('[name="Suche"]').attr({ 2209 'name': 'keywords', 2210 'placeholder': 'Suche' 2211 }); 2212}); 2213 2214jQuery(document).ready(function () { 2215 2216 if (jQuery('select#select_adress').length) { 2217 2218 jQuery('select#select_adress').find('option').each(function (idx, elem) { 2219 if (elem && elem.value) { 2220 if (elem.value.trim() == ',') elem.remove(); 2221 }; 2222 }); 2223 2224 }; 2225}); 2226 2227/* Script für Slider text */ 2228 2229jQuery(document).ready(function () { 2230 jQuery('div[id^=place]').each(function (idx, elem) { 2231 var id = jQuery(elem).attr('id'); 2232 jQuery('.slider-text[place="' + id + '"]').append(elem); 2233 }); 2234}); 2235 2236/* Script für select language function */ 2237 2238jQuery(document).ready(function () { 2239 jQuery('.mod_changelanguage').find('select').bind({ 2240 'change keyup': function (evt) { 2241 location.href = (jQuery(this).val()); 2242 } 2243 }) 2244}); 2245 2246jQuery(document).ready(function () { 2247 /* Link remove */ 2248 /*jQuery('a[title="Leistungen"]').on('click', function(e) { 2249 e.preventDefault(); 2250 });*/ 2251 jQuery(document).ready(function () { 2252 $('.carosel-control-right').click(function () { 2253 $(this).blur(); 2254 $(this).parent().find('.carosel-item').first().insertAfter($(this).parent().find('.carosel-item').last()); 2255 $(this).parent().find('.carosel-item').removeClass('active-effect'); 2256 var that = this; 2257 setTimeout(function () { 2258 $(that).parent().find('.carosel-item').addClass('active-effect'); 2259 }, 100); 2260 // $(this).parent().find('.carosel-item').first().addClass( 'active-effect' ); 2261 // $(this).parent().find('.carosel-item :visible').last().addClass( 'active-effect' ); 2262 }); 2263 $('.carosel-control-left').click(function () { 2264 $(this).blur(); 2265 $(this).parent().find('.carosel-item').last().insertBefore($(this).parent().find('.carosel-item').first()); 2266 $(this).parent().find('.carosel-item').removeClass('active-effect'); 2267 var that = this; 2268 setTimeout(function () { 2269 $(that).parent().find('.carosel-item').addClass('active-effect'); 2270 }, 100); 2271 // $(this).parent().find('.carosel-item').first().addClass( 'active-effect' ); 2272 // $(this).parent().find('.carosel-item :visible').last().addClass( 'active-effect' ); 2273 }); 2274 }); 2275 2276 /* Sticky Header */ 2277 if (jQuery('#first-navi').length) { 2278 var topnav = jQuery('#first-navi').offset().top; 2279 jQuery(window).scroll(function () { 2280 var scrollpos = jQuery(this).scrollTop(); 2281 if (scrollpos >= topnav) { 2282 jQuery('#first-navi').addClass('fix'); 2283 } 2284 if (scrollpos < topnav) { 2285 jQuery('#first-navi').removeClass('fix'); 2286 } 2287 }); 2288 } 2289 2290 jQuery("#quick-one").click(function () { 2291 jQuery("#quick-one").toggleClass("active"); 2292 jQuery("#quick-two").removeClass("active"); 2293 jQuery("#quick-three").removeClass("active"); 2294 }); 2295 2296 jQuery("#quick-two").click(function () { 2297 jQuery("#quick-one").removeClass("active"); 2298 jQuery("#quick-two").toggleClass("active"); 2299 jQuery("#quick-three").removeClass("active"); 2300 }); 2301 2302 jQuery("#quick-three").click(function () { 2303 jQuery("#quick-one").removeClass("active"); 2304 jQuery("#quick-two").removeClass("active"); 2305 jQuery("#quick-three").toggleClass("active"); 2306 }); 2307 2308 /* Modalfenster für Werbeaktionen etc. */ 2309 function setCookie() { 2310 var d = new Date(); 2311 d.setTime(d.getTime() + (30 * 86400000)); //30 Tage 2312 document.cookie = 'aktion=gesehen;expires=' + d.toUTCString(); 2313 } 2314 jQuery('.modal').click(function () { 2315 jQuery(this).css('display', 'none');
2316 setCookie(); 2317 }); 2318 2319 2320 jQuery(window).on('load', function () { 2321 var elements = document.getElementsByClassName('txt-rotate'); 2322 for (var i = 0; i < elements.length; i++) { 2323 var toRotate = elements[i].getAttribute('data-rotate'); 2324 var period = elements[i].getAttribute('data-period'); 2325 if (toRotate) { 2326 new TxtRotate(elements[i], JSON.parse(toRotate), period); 2327 } 2328 } 2329 jQuery('.infobox').addClass('animate'); 2330 jQuery('.infoboxen lefttLst').addClass('animate'); 2331 jQuery('.infoboxen rightLst').addClass('animate'); 2332 }); 2333 jQuery('#sidebarCollapse').on('click', function () { 2334 // open sidebar 2335 jQuery('.collapsible_area').toggleClass('active'); 2336 2337 }); 2338 2339}); 2340 2341 2342 2343 2344if (settings_buttonup) { 2345 jQuery(document).ready(function () { 2346 /* jQuery( '#main' ).append( '<a id="mbutton"></a>' ); */ 2347 2348 if (jQuery('#mbutton').length) { 2349 var btn = jQuery('#mbutton'); 2350 2351 jQuery(window).scroll(function () { 2352 if (jQuery(window).scrollTop() > 300) { 2353 btn.addClass('show'); 2354 2355 if (typeof (window.recaptcha) == 'object') { 2356 jQuery('#mbutton').css({ 2357 right: '10px', 2358 bottom: '78px' 2359 }); 2360 }; 2361 } else { 2362 btn.removeClass('show'); 2363 } 2364 }); 2365 2366 btn.on('click', function (e) { 2367 e.preventDefault(); 2368 jQuery('html, body').animate({ 2369 scrollTop: 0 2370 }, '300'); 2371 }); 2372 }; 2373 }); 2374}; 2375 2376 2377 2378if (settings_autotarget) { 2379 jQuery(document).ready(function () { 2380 jQuery('a').each(function (idx, elem) { 2381 var href = jQuery(elem).attr('href'); 2382 var target = jQuery(elem).attr('target'); 2383 var firstdomain = location.hostname.split('.')[location.hostname.split('.').length - 2]; 2384 if (typeof (href) == 'string' && typeof (target) == 'undefined') { 2385 if (href.indexOf('http') == 0 || href.indexOf('//') == 0) { // () && href.indexOf(firstdomain) < 0 2386 jQuery(elem).attr({ 2387 'target': '_blank' 2388 }); 2389 }; 2390 }; 2391 }); 2392 }); 2393}; 2394 2395 2396var createCookie = function (name, value, days) { 2397 var expires; 2398 2399 if (days) { 2400 var date = new Date(); 2401 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 2402 expires = "; expires=" + date.toGMTString(); 2403 } else { 2404 expires = ""; 2405 } 2406 document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=/"; 2407} 2408 2409var readCookie = function readCookie(name) { 2410 var nameEQ = encodeURIComponent(name) + "="; 2411 var ca = document.cookie.split(';'); 2412 for (var i = 0; i < ca.length; i++) { 2413 var c = ca[i]; 2414 while (c.charAt(0) === ' ') 2415 c = c.substring(1, c.length); 2416 if (c.indexOf(nameEQ) === 0) 2417 return decodeURIComponent(c.substring(nameEQ.length, c.length)); 2418 } 2419 return null; 2420} 2421 2422var eraseCookie = function (name) { 2423 createCookie(name, "", -1); 2424}; 2425 2426 2427 2428 2429 2430 2431 2432 2433if (settings_iframe2video) { 2434 jQuery(document).ready(function () { 2435 setTimeout(function () { 2436 jQuery('iframe').each(function (idx, elem) { 2437 if (jQuery(elem).attr('src') && jQuery(elem).attr('src').indexOf('.mp4') > -1) { 2438 var poster = jQuery(elem).attr('poster'); 2439 if (poster) poster = ' poster="' + poster + '"'; 2440 else poster = ''; 2441 jQuery(elem).replaceWith('<video class="evideo" ' + poster + ' controls><source src="' + jQuery(elem).attr('src') + '" type="video/mp4">Ihr Browser kann dieses Video-Format nicht wiedergeben. // Your browser does not support the video tag.</video>'); 2442 }; 2443 }); 2444 2445 setTimeout(function () { 2446 var video = document.querySelector('video'); 2447 if (video) { 2448 video.addEventListener('ended', function () { 2449 video.load(); 2450 }); 2451 jQuery(video).attr('autoplay', false); 2452 var e = jQuery('video')[0]; 2453 /* e.play(); */ 2454 }; 2455 }, 500); 2456 }, 500); 2457 }); 2458}; 2459 2460 2461 2462 2463 2464 2465 2466 2467
2468if (settings_b3slider) { 2469 jQuery(document).ready(function () { 2470 var b3slider = window.b3slider = function () { 2471 var timerevt = null; 2472 2473 jQuery('button.leftLst[pid]').each(function (idx, elem) { 2474 var pid = jQuery(elem).attr('pid'); 2475 var targ = jQuery('div[pid="' + pid + '"]'); 2476 var btnLeft = jQuery('button[pid="' + pid + '"].leftLst'); 2477 var btnRight = jQuery('button[pid="' + pid + '"].rightLst'); 2478 2479 var v = targ.attr('transformX') || 0; 2480 2481 targ.attr('transformX', v); 2482 2483 var first_width = jQuery(targ.find('.item')[0]).width(); 2484 var width_outer = targ.width(); 2485 var width_inner = targ.find('.MultiCarousel-inner').width(); 2486 2487 if (v == 0) { 2488 btnLeft.css({ 2489 opacity: 0.5 2490 }) 2491 } else { 2492 btnLeft.css({ 2493 opacity: 1.0 2494 }); 2495 }; 2496 2497 if (width_outer >= width_inner) { 2498 btnRight.css({ 2499 opacity: 0.5 2500 }) 2501 } else { 2502 btnRight.css({ 2503 opacity: 1.0 2504 }); 2505 }; 2506 2507 2508 targ.swipe({ 2509 swipeStatus: function (event, phase, direction, distance, duration, fingers, fingerData, currentDirection) { 2510 switch (phase) { 2511 case 'start': 2512 break; 2513 2514 case 'move': 2515 var dist = 0; 2516 if (direction == 'left') dist = -distance; 2517 if (direction == 'right') dist = distance; 2518 2519 var v = targ.attr('transformX') || 0; 2520 v = +v; 2521 2522 v += dist; 2523 2524 /* 2525 targ.find('.MultiCarousel-inner').css({ 2526 'transform': 'translateX(-' + v + 'px)', 2527 'transition-duration': '300ms' 2528 }); 2529 */ 2530 break; 2531 2532 case 'end': 2533 while (distance > 0) { 2534 if (direction == 'right' && distance >= 64) jQuery('button[pid="' + pid + '"]' + '.leftLst').mousedown(); 2535 if (direction == 'left' && distance >= 64) jQuery('button[pid="' + pid + '"]' + '.rightLst').mousedown(); 2536 if (direction == 'right' && distance >= 64) jQuery('button[pid="' + pid + '"]' + '.leftLst').mouseup(); 2537 if (direction == 'left' && distance >= 64) jQuery('button[pid="' + pid + '"]' + '.rightLst').mouseup(); 2538 distance -= 64; 2539 }; 2540 break; 2541 2542 default: 2543 break; 2544 } 2545 } 2546 }); 2547 2548 }); 2549
2550 jQuery('button.leftLst[pid],button.rightLst[pid]').unbind().bind({ 2551 'mousedown': function () { 2552 2553 jQuery(this).attr('dragging', true); 2554 clearInterval(timerevt); 2555 var that = this; 2556 2557 var pid = jQuery(that).attr('pid'); 2558 var btnLeft = jQuery('button[pid="' + pid + '"].leftLst'); 2559 var btnRight = jQuery('button[pid="' + pid + '"].rightLst'); 2560 var targ = jQuery('div[pid="' + pid + '"]'); 2561 var right = jQuery(this).hasClass('rightLst'); 2562 var cnt = targ.find('.item').length; 2563 var first_width = jQuery(targ.find('.item')[0]).width(); 2564 var width = targ.find('.MultiCarousel-inner').width() - targ.width(); 2565 2566 window.that = that; 2567 window.targ = targ; 2568 2569 var nextstep = function () { 2570 var v = targ.attr('transformX') || 0; 2571 v = +v; 2572 2573 var stepping = 50; 2574 stepping = width / (cnt + 1); 2575 stepping = first_width; 2576 v += right ? stepping : -stepping; 2577 v = Math.round(v / stepping) * stepping; 2578 if (v < 0) v = 0; 2579 if (v > width) v = width; 2580 2581 targ.find('.MultiCarousel-inner').css({ 2582 'transform': 'translateX(-' + v + 'px)', 2583 'transition-duration': '1000ms' 2584 }); 2585 2586 2587 targ.attr('transformX', v); 2588 2589 if (v == 0) btnLeft.css({ 2590 opacity: 0.5 2591 }); 2592 else btnLeft.css({ 2593 opacity: 1.0 2594 }); 2595 if (v == width) btnRight.css({ 2596 opacity: 0.5 2597 }); 2598 else btnRight.css({ 2599 opacity: 1.0 2600 }); 2601 }; 2602 2603 timerevt = setInterval(function () { 2604 nextstep(); 2605 }, 500); 2606 2607 nextstep(); 2608 }, 2609 'mouseup': function () { 2610 2611 jQuery(this).attr('dragging', false); 2612 clearInterval(timerevt); 2613 timerevt = null; 2614 }, 2615 'mousemove': function () { 2616 if (jQuery(this).attr('dragging')) { 2617 2618 }; 2619 } 2620 }); 2621 }; 2622 2623 2624 2625 2626 jQuery(window).resize(function () { 2627 // ResCarouselSize(); 2628 b3slider(); 2629 }); 2630 2631 // ResCarouselSize(); 2632 b3slider(); 2633 2634 }); 2635}; 2636 2637(function (w) { 2638 2639 w.URLSearchParams = w.URLSearchParams || function (searchString) { 2640 var self = this; 2641 self.searchString = searchString; 2642 self.get = function (name) { 2643 var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString); 2644 if (results == null) { 2645 return null; 2646 } else { 2647 return decodeURI(results[1]) || 0; 2648 } 2649 }; 2650 } 2651 2652})(window) 2653 2654if (settings_countup) { 2655 jQuery(document).ready(function () { 2656 2657 jQuery('.countup').each(function (idx, elem) { 2658 jQuery(elem).find('span').each(function (idx, elem) { 2659 elem = jQuery(elem); 2660 var style = elem.attr('style'); 2661 if (style && style.indexOf('line-through') > -1) { 2662 style = style.replaceAll('text-decoration: line-through;', ''); 2663 elem.attr('style', style); 2664 var count_end = parseInt(jQuery(elem).text()); 2665 if (count_end > 0) { 2666 var ele = elem, 2667 number = 0, 2668 step = count_end > 500 ? (count_end > 4000 ? 16 : 9) : 1, 2669 timer = setInterval(function () { 2670 if (ele.is(":visible")) { // { // if (ele.is(":visible")) 2671 if (number == count_end || number > count_end) { 2672 clearInterval(timer); 2673 ele.text(count_end); 2674 } else { 2675 ele.text(number); 2676 }; 2677 number += step; 2678 }; 2679 }, 10); 2680 }; 2681 }; 2682 }); 2683 }); 2684 2685 }); 2686}; 2687
2688if (settings_autotarget) { 2689 jQuery(document).ready(function () { 2690 jQuery('a').each(function (idx, elem) { 2691 2692 var target = jQuery(elem).attr('target'); 2693 var href = jQuery(elem).attr('href'); 2694 if (href && !target && href.toLowerCase().indexOf('.pdf') > 0) { 2695 jQuery(elem).attr('target', '_blank'); 2696 }; 2697 2698 }); 2699 }); 2700}; 2701 2702if (settings_immoautoformfill) { 2703 jQuery(document).ready(function () { 2704 if (jQuery('input[name=Objekt]').length && getQueryStringParameter('obid')) { 2705 jQuery('input[name=Objekt]').val(getQueryStringParameter('obid')); 2706 jQuery('.immo-form-objekt-autohide').removeClass('immo-form-objekt-autohide'); 2707 }; 2708 }); 2709}; 2710 2711if (settings_potrait_no_title_popup) { 2712 jQuery(document).ready(function () { 2713 jQuery('.portrait').each(function () { 2714 jQuery(this).find('img').each(function (idx, elem) { 2715 jQuery(elem).attr({ 2716 title: '' 2717 }); 2718 }); 2719 }); 2720 }); 2721};
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.