1 | /* |
---|
2 | |
---|
3 | _/ _/_/ _/_/_/_/_/ _/ |
---|
4 | _/ _/ _/ _/_/ _/ _/ _/_/_/ _/_/_/ |
---|
5 | _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ |
---|
6 | _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ |
---|
7 | _/ _/_/ _/ _/ _/_/ _/_/_/ _/_/_/ _/ _/ |
---|
8 | _/ |
---|
9 | _/ |
---|
10 | |
---|
11 | Created by David Kaneda <http://www.davidkaneda.com> |
---|
12 | Documentation and issue tracking on Google Code <http://code.google.com/p/jqtouch/> |
---|
13 | |
---|
14 | Special thanks to Jonathan Stark <http://jonathanstark.com/> |
---|
15 | and pinch/zoom <http://www.pinchzoom.com/> |
---|
16 | |
---|
17 | (c) 2009 by jQTouch project members. |
---|
18 | See LICENSE.txt for license. |
---|
19 | |
---|
20 | $Revision: 109 $ |
---|
21 | $Date: 2009-10-06 12:23:30 -0400 (Tue, 06 Oct 2009) $ |
---|
22 | $LastChangedBy: davidcolbykaneda $ |
---|
23 | |
---|
24 | */ |
---|
25 | |
---|
26 | (function($) { |
---|
27 | $.jQTouch = function(options) { |
---|
28 | |
---|
29 | // Set support values |
---|
30 | $.support.WebKitCSSMatrix = (typeof WebKitCSSMatrix == "object"); |
---|
31 | $.support.touch = (typeof Touch == "object"); |
---|
32 | $.support.WebKitAnimationEvent = (typeof WebKitTransitionEvent == "object"); |
---|
33 | |
---|
34 | // Initialize internal variables |
---|
35 | var $body, |
---|
36 | $head=$('head'), |
---|
37 | hist=[], |
---|
38 | newPageCount=0, |
---|
39 | jQTSettings={}, |
---|
40 | hashCheck, |
---|
41 | currentPage, |
---|
42 | orientation, |
---|
43 | isMobileWebKit = RegExp(" Mobile/").test(navigator.userAgent), |
---|
44 | tapReady=true, |
---|
45 | lastAnimationTime=0, |
---|
46 | touchSelectors=[], |
---|
47 | publicObj={}, |
---|
48 | extensions=$.jQTouch.prototype.extensions, |
---|
49 | defaultAnimations=['slide','flip','slideup','swap','cube','pop','dissolve','fade','back'], |
---|
50 | animations=[], |
---|
51 | hairextensions=''; |
---|
52 | |
---|
53 | // Get the party started |
---|
54 | init(options); |
---|
55 | |
---|
56 | function init(options) { |
---|
57 | |
---|
58 | var defaults = { |
---|
59 | addGlossToIcon: true, |
---|
60 | backSelector: '.back, .cancel, .goback', |
---|
61 | cacheGetRequests: true, |
---|
62 | cubeSelector: '.cube', |
---|
63 | dissolveSelector: '.dissolve', |
---|
64 | fadeSelector: '.fade', |
---|
65 | fixedViewport: true, |
---|
66 | flipSelector: '.flip', |
---|
67 | formSelector: 'form', |
---|
68 | fullScreen: true, |
---|
69 | fullScreenClass: 'fullscreen', |
---|
70 | icon: null, |
---|
71 | touchSelector: 'a, .touch', |
---|
72 | popSelector: '.pop', |
---|
73 | preloadImages: false, |
---|
74 | slideSelector: 'body > * > ul li a', |
---|
75 | slideupSelector: '.slideup', |
---|
76 | startupScreen: null, |
---|
77 | statusBar: 'default', // other options: black-translucent, black |
---|
78 | submitSelector: '.submit', |
---|
79 | swapSelector: '.swap', |
---|
80 | useAnimations: true, |
---|
81 | useFastTouch: true // Experimental. |
---|
82 | }; |
---|
83 | jQTSettings = $.extend({}, defaults, options); |
---|
84 | |
---|
85 | // Preload images |
---|
86 | if (jQTSettings.preloadImages) { |
---|
87 | for (var i = jQTSettings.preloadImages.length - 1; i >= 0; i--){ |
---|
88 | (new Image()).src = jQTSettings.preloadImages[i]; |
---|
89 | }; |
---|
90 | } |
---|
91 | // Set icon |
---|
92 | if (jQTSettings.icon) { |
---|
93 | var precomposed = (jQTSettings.addGlossToIcon) ? '' : '-precomposed'; |
---|
94 | hairextensions += '<link rel="apple-touch-icon' + precomposed + '" href="' + jQTSettings.icon + '" />'; |
---|
95 | } |
---|
96 | // Set startup screen |
---|
97 | if (jQTSettings.startupScreen) { |
---|
98 | hairextensions += '<link rel="apple-touch-startup-image" href="' + jQTSettings.startupScreen + '" />'; |
---|
99 | } |
---|
100 | // Set viewport |
---|
101 | if (jQTSettings.fixedViewport) { |
---|
102 | hairextensions += '<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;"/>'; |
---|
103 | } |
---|
104 | // Set full-screen |
---|
105 | if (jQTSettings.fullScreen) { |
---|
106 | hairextensions += '<meta name="apple-mobile-web-app-capable" content="yes" />'; |
---|
107 | if (jQTSettings.statusBar) { |
---|
108 | hairextensions += '<meta name="apple-mobile-web-app-status-bar-style" content="' + jQTSettings.statusBar + '" />'; |
---|
109 | } |
---|
110 | } |
---|
111 | if (hairextensions) $head.append(hairextensions); |
---|
112 | |
---|
113 | // Initialize on document load: |
---|
114 | $(document).ready(function(){ |
---|
115 | |
---|
116 | // Add extensions |
---|
117 | for (var i in extensions) |
---|
118 | { |
---|
119 | var fn = extensions[i]; |
---|
120 | if ($.isFunction(fn)) |
---|
121 | { |
---|
122 | $.extend(publicObj, fn(publicObj)); |
---|
123 | } |
---|
124 | } |
---|
125 | |
---|
126 | // Add animations |
---|
127 | for (var i in defaultAnimations) |
---|
128 | { |
---|
129 | var name = defaultAnimations[i]; |
---|
130 | var selector = jQTSettings[name + 'Selector']; |
---|
131 | if (typeof(selector) == 'string') { |
---|
132 | addAnimation({name:name, selector:selector}); |
---|
133 | } |
---|
134 | } |
---|
135 | |
---|
136 | touchSelectors.push('input'); |
---|
137 | touchSelectors.push(jQTSettings.touchSelector); |
---|
138 | touchSelectors.push(jQTSettings.backSelector); |
---|
139 | touchSelectors.push(jQTSettings.submitSelector); |
---|
140 | $(touchSelectors.join(', ')).css('-webkit-touch-callout', 'none'); |
---|
141 | $(jQTSettings.backSelector).tap(liveTap); |
---|
142 | $(jQTSettings.submitSelector).tap(submitParentForm); |
---|
143 | |
---|
144 | $body = $('body'); |
---|
145 | |
---|
146 | if (jQTSettings.fullScreenClass && window.navigator.standalone == true) { |
---|
147 | $body.addClass(jQTSettings.fullScreenClass + ' ' + jQTSettings.statusBar); |
---|
148 | } |
---|
149 | |
---|
150 | // Create custom live events |
---|
151 | $body |
---|
152 | .bind('touchstart', handleTouch) |
---|
153 | .bind('orientationchange', updateOrientation) |
---|
154 | .trigger('orientationchange') |
---|
155 | .submit(submitForm); |
---|
156 | |
---|
157 | if (jQTSettings.useFastTouch && $.support.touch) |
---|
158 | { |
---|
159 | $body.click(function(e){ |
---|
160 | var $el = $(e.target); |
---|
161 | if ($el.attr('target') == '_blank' || $el.attr('rel') == 'external' || $el.is('input[type="checkbox"]')) |
---|
162 | { |
---|
163 | return true; |
---|
164 | } else { |
---|
165 | return false; |
---|
166 | } |
---|
167 | }); |
---|
168 | |
---|
169 | // This additionally gets rid of form focusses |
---|
170 | $body.mousedown(function(e){ |
---|
171 | var timeDiff = (new Date()).getTime() - lastAnimationTime; |
---|
172 | if (timeDiff < 200) |
---|
173 | { |
---|
174 | return false; |
---|
175 | } |
---|
176 | }); |
---|
177 | } |
---|
178 | |
---|
179 | // Make sure exactly one child of body has "current" class |
---|
180 | if ($('body > .current').length == 0) { |
---|
181 | currentPage = $('body > *:first'); |
---|
182 | } else { |
---|
183 | currentPage = $('body > .current:first'); |
---|
184 | $('body > .current').removeClass('current'); |
---|
185 | } |
---|
186 | |
---|
187 | // Go to the top of the "current" page |
---|
188 | $(currentPage).addClass('current'); |
---|
189 | location.hash = $(currentPage).attr('id'); |
---|
190 | addPageToHistory(currentPage); |
---|
191 | scrollTo(0, 0); |
---|
192 | dumbLoopStart(); |
---|
193 | }); |
---|
194 | } |
---|
195 | |
---|
196 | // PUBLIC FUNCTIONS |
---|
197 | function goBack(to) { |
---|
198 | // Init the param |
---|
199 | if (hist.length > 1) { |
---|
200 | var numberOfPages = Math.min(parseInt(to || 1, 10), hist.length-1); |
---|
201 | |
---|
202 | // Search through the history for an ID |
---|
203 | if( isNaN(numberOfPages) && typeof(to) === "string" && to != '#' ) { |
---|
204 | for( var i=1, length=hist.length; i < length; i++ ) { |
---|
205 | if( '#' + hist[i].id === to ) { |
---|
206 | numberOfPages = i; |
---|
207 | break; |
---|
208 | } |
---|
209 | } |
---|
210 | } |
---|
211 | |
---|
212 | // If still nothing, assume one |
---|
213 | if( isNaN(numberOfPages) || numberOfPages < 1 ) { |
---|
214 | numberOfPages = 1; |
---|
215 | }; |
---|
216 | |
---|
217 | // Grab the current page for the "from" info |
---|
218 | var animation = hist[0].animation; |
---|
219 | var fromPage = hist[0].page; |
---|
220 | |
---|
221 | // Remove all pages in front of the target page |
---|
222 | hist.splice(0, numberOfPages); |
---|
223 | |
---|
224 | // Grab the target page |
---|
225 | var toPage = hist[0].page; |
---|
226 | |
---|
227 | // Make the animations |
---|
228 | animatePages(fromPage, toPage, animation, true); |
---|
229 | |
---|
230 | return publicObj; |
---|
231 | } else { |
---|
232 | console.error('No pages in history.'); |
---|
233 | return false; |
---|
234 | } |
---|
235 | } |
---|
236 | function goTo(toPage, animation) { |
---|
237 | var fromPage = hist[0].page; |
---|
238 | |
---|
239 | if (typeof(toPage) === 'string') { |
---|
240 | toPage = $(toPage); |
---|
241 | } |
---|
242 | if (typeof(animation) === 'string') { |
---|
243 | for (var i = animations.length - 1; i >= 0; i--){ |
---|
244 | if (animations[i].name === animation) |
---|
245 | { |
---|
246 | animation = animations[i]; |
---|
247 | break; |
---|
248 | } |
---|
249 | } |
---|
250 | } |
---|
251 | if (animatePages(fromPage, toPage, animation)) { |
---|
252 | addPageToHistory(toPage, animation); |
---|
253 | return publicObj; |
---|
254 | } |
---|
255 | else |
---|
256 | { |
---|
257 | console.error('Could not animate pages.'); |
---|
258 | return false; |
---|
259 | } |
---|
260 | } |
---|
261 | function getOrientation() { |
---|
262 | return orientation; |
---|
263 | } |
---|
264 | |
---|
265 | // PRIVATE FUNCTIONS |
---|
266 | function liveTap(e){ |
---|
267 | |
---|
268 | // Grab the clicked element |
---|
269 | var $el = $(e.target); |
---|
270 | |
---|
271 | if ($el.attr('nodeName')!=='A'){ |
---|
272 | $el = $el.parent('a'); |
---|
273 | } |
---|
274 | |
---|
275 | var target = $el.attr('target'), |
---|
276 | hash = $el.attr('hash'), |
---|
277 | animation=null; |
---|
278 | |
---|
279 | if (tapReady == false || !$el.length) { |
---|
280 | console.warn('Not able to tap element.') |
---|
281 | return false; |
---|
282 | } |
---|
283 | |
---|
284 | if ($el.attr('target') == '_blank' || $el.attr('rel') == 'external') |
---|
285 | { |
---|
286 | return true; |
---|
287 | } |
---|
288 | |
---|
289 | // Figure out the animation to use |
---|
290 | for (var i = animations.length - 1; i >= 0; i--){ |
---|
291 | if ($el.is(animations[i].selector)) { |
---|
292 | animation = animations[i]; |
---|
293 | break; |
---|
294 | } |
---|
295 | }; |
---|
296 | |
---|
297 | // User clicked an internal link, fullscreen mode |
---|
298 | if (target == '_webapp') { |
---|
299 | window.location = $el.attr('href'); |
---|
300 | } |
---|
301 | // User clicked a back button |
---|
302 | else if ($el.is(jQTSettings.backSelector)) { |
---|
303 | goBack(hash); |
---|
304 | } |
---|
305 | // Branch on internal or external href |
---|
306 | else if (hash && hash!='#') { |
---|
307 | $el.addClass('active'); |
---|
308 | goTo($(hash).data('referrer', $el), animation); |
---|
309 | } else { |
---|
310 | $el.addClass('loading active'); |
---|
311 | showPageByHref($el.attr('href'), { |
---|
312 | animation: animation, |
---|
313 | callback: function(){ |
---|
314 | $el.removeClass('loading'); setTimeout($.fn.unselect, 250, $el); |
---|
315 | }, |
---|
316 | $referrer: $el |
---|
317 | }); |
---|
318 | } |
---|
319 | return false; |
---|
320 | } |
---|
321 | function addPageToHistory(page, animation) { |
---|
322 | // Grab some info |
---|
323 | var pageId = page.attr('id'); |
---|
324 | |
---|
325 | // Prepend info to page history |
---|
326 | hist.unshift({ |
---|
327 | page: page, |
---|
328 | animation: animation, |
---|
329 | id: pageId |
---|
330 | }); |
---|
331 | } |
---|
332 | function animatePages(fromPage, toPage, animation, backwards) { |
---|
333 | // Error check for target page |
---|
334 | if(toPage.length === 0){ |
---|
335 | $.fn.unselect(); |
---|
336 | console.error('Target element is missing.'); |
---|
337 | return false; |
---|
338 | } |
---|
339 | |
---|
340 | // Collapse the keyboard |
---|
341 | $(':focus').blur(); |
---|
342 | |
---|
343 | // Make sure we are scrolled up to hide location bar |
---|
344 | scrollTo(0, 0); |
---|
345 | |
---|
346 | // Define callback to run after animation completes |
---|
347 | var callback = function(event){ |
---|
348 | |
---|
349 | if (animation) |
---|
350 | { |
---|
351 | toPage.removeClass('in reverse ' + animation.name); |
---|
352 | fromPage.removeClass('current out reverse ' + animation.name); |
---|
353 | } |
---|
354 | else |
---|
355 | { |
---|
356 | fromPage.removeClass('current'); |
---|
357 | } |
---|
358 | |
---|
359 | toPage.trigger('pageAnimationEnd', { direction: 'in' }); |
---|
360 | fromPage.trigger('pageAnimationEnd', { direction: 'out' }); |
---|
361 | |
---|
362 | clearInterval(dumbLoop); |
---|
363 | currentPage = toPage; |
---|
364 | location.hash = currentPage.attr('id'); |
---|
365 | dumbLoopStart(); |
---|
366 | |
---|
367 | var $originallink = toPage.data('referrer'); |
---|
368 | if ($originallink) { |
---|
369 | $originallink.unselect(); |
---|
370 | } |
---|
371 | lastAnimationTime = (new Date()).getTime(); |
---|
372 | tapReady = true; |
---|
373 | } |
---|
374 | |
---|
375 | fromPage.trigger('pageAnimationStart', { direction: 'out' }); |
---|
376 | toPage.trigger('pageAnimationStart', { direction: 'in' }); |
---|
377 | |
---|
378 | if ($.support.WebKitAnimationEvent && animation && jQTSettings.useAnimations) { |
---|
379 | toPage.one('webkitAnimationEnd', callback); |
---|
380 | tapReady = false; |
---|
381 | toPage.addClass(animation.name + ' in current ' + (backwards ? ' reverse' : '')); |
---|
382 | fromPage.addClass(animation.name + ' out' + (backwards ? ' reverse' : '')); |
---|
383 | } else { |
---|
384 | toPage.addClass('current'); |
---|
385 | callback(); |
---|
386 | } |
---|
387 | |
---|
388 | return true; |
---|
389 | } |
---|
390 | function dumbLoopStart() { |
---|
391 | dumbLoop = setInterval(function(){ |
---|
392 | var curid = currentPage.attr('id'); |
---|
393 | if (location.hash == '') { |
---|
394 | location.hash = '#' + curid; |
---|
395 | } else if (location.hash != '#' + curid) { |
---|
396 | try { |
---|
397 | goBack(location.hash) |
---|
398 | } catch(e) { |
---|
399 | console.error('Unknown hash change.'); |
---|
400 | } |
---|
401 | } |
---|
402 | }, 100); |
---|
403 | } |
---|
404 | function insertPages(nodes, animation) { |
---|
405 | var targetPage = null; |
---|
406 | $(nodes).each(function(index, node){ |
---|
407 | var $node = $(this); |
---|
408 | if (!$node.attr('id')) { |
---|
409 | $node.attr('id', 'page-' + (++newPageCount)); |
---|
410 | } |
---|
411 | $node.appendTo($body); |
---|
412 | if ($node.hasClass('current') || !targetPage ) { |
---|
413 | targetPage = $node; |
---|
414 | } |
---|
415 | }); |
---|
416 | if (targetPage !== null) { |
---|
417 | goTo(targetPage, animation); |
---|
418 | return targetPage; |
---|
419 | } |
---|
420 | else |
---|
421 | { |
---|
422 | return false; |
---|
423 | } |
---|
424 | } |
---|
425 | function showPageByHref(href, options) { |
---|
426 | var defaults = { |
---|
427 | data: null, |
---|
428 | method: 'GET', |
---|
429 | animation: null, |
---|
430 | callback: null, |
---|
431 | $referrer: null |
---|
432 | }; |
---|
433 | |
---|
434 | var settings = $.extend({}, defaults, options); |
---|
435 | |
---|
436 | if (href != '#') |
---|
437 | { |
---|
438 | $.ajax({ |
---|
439 | url: href, |
---|
440 | data: settings.data, |
---|
441 | type: settings.method, |
---|
442 | success: function (data, textStatus) { |
---|
443 | var firstPage = insertPages(data, settings.animation); |
---|
444 | if (firstPage) |
---|
445 | { |
---|
446 | if (settings.method == 'GET' && jQTSettings.cacheGetRequests && settings.$referrer) |
---|
447 | { |
---|
448 | settings.$referrer.attr('href', '#' + firstPage.attr('id')); |
---|
449 | } |
---|
450 | if (settings.callback) { |
---|
451 | settings.callback(true); |
---|
452 | } |
---|
453 | } |
---|
454 | }, |
---|
455 | error: function (data) { |
---|
456 | if (settings.$referrer) settings.$referrer.unselect(); |
---|
457 | if (settings.callback) { |
---|
458 | settings.callback(false); |
---|
459 | } |
---|
460 | } |
---|
461 | }); |
---|
462 | } |
---|
463 | else if ($referrer) |
---|
464 | { |
---|
465 | $referrer.unselect(); |
---|
466 | } |
---|
467 | } |
---|
468 | function submitForm(e, callback){ |
---|
469 | var $form = (typeof(e)==='string') ? $(e) : $(e.target); |
---|
470 | |
---|
471 | if ($form.length && $form.is(jQTSettings.formSelector) && $form.attr('action')) { |
---|
472 | showPageByHref($form.attr('action'), { |
---|
473 | data: $form.serialize(), |
---|
474 | method: $form.attr('method') || "POST", |
---|
475 | animation: animations[0] || null, |
---|
476 | callback: callback |
---|
477 | }); |
---|
478 | return false; |
---|
479 | } |
---|
480 | return true; |
---|
481 | } |
---|
482 | function submitParentForm(e){ |
---|
483 | var $form = $(this).closest('form'); |
---|
484 | if ($form.length) |
---|
485 | { |
---|
486 | evt = jQuery.Event("submit"); |
---|
487 | evt.preventDefault(); |
---|
488 | $form.trigger(evt); |
---|
489 | return false; |
---|
490 | } |
---|
491 | return true; |
---|
492 | } |
---|
493 | function addAnimation(animation) { |
---|
494 | if (typeof(animation.selector) == 'string' && typeof(animation.name) == 'string') { |
---|
495 | animations.push(animation); |
---|
496 | $(animation.selector).tap(liveTap); |
---|
497 | touchSelectors.push(animation.selector); |
---|
498 | } |
---|
499 | } |
---|
500 | function updateOrientation() { |
---|
501 | orientation = window.innerWidth < window.innerHeight ? 'profile' : 'landscape'; |
---|
502 | $body.removeClass('profile landscape').addClass(orientation).trigger('turn', {orientation: orientation}); |
---|
503 | // scrollTo(0, 0); |
---|
504 | } |
---|
505 | function handleTouch(e) { |
---|
506 | |
---|
507 | var $el = $(e.target); |
---|
508 | |
---|
509 | // Only handle touchSelectors |
---|
510 | if (!$(e.target).is(touchSelectors.join(', '))) |
---|
511 | { |
---|
512 | var $link = $(e.target).closest('a'); |
---|
513 | |
---|
514 | if ($link.length){ |
---|
515 | $el = $link; |
---|
516 | } else { |
---|
517 | return; |
---|
518 | } |
---|
519 | } |
---|
520 | if (event) |
---|
521 | { |
---|
522 | var hoverTimeout = null, |
---|
523 | startX = event.changedTouches[0].clientX, |
---|
524 | startY = event.changedTouches[0].clientY, |
---|
525 | startTime = (new Date).getTime(), |
---|
526 | deltaX = 0, |
---|
527 | deltaY = 0, |
---|
528 | deltaT = 0; |
---|
529 | |
---|
530 | // Let's bind these after the fact, so we can keep some internal values |
---|
531 | $el.bind('touchmove', touchmove).bind('touchend', touchend); |
---|
532 | |
---|
533 | hoverTimeout = setTimeout(function(){ |
---|
534 | $el.makeActive(); |
---|
535 | }, 100); |
---|
536 | |
---|
537 | } |
---|
538 | |
---|
539 | // Private touch functions (TODO: insert dirty joke) |
---|
540 | function touchmove(e) { |
---|
541 | |
---|
542 | updateChanges(); |
---|
543 | var absX = Math.abs(deltaX); |
---|
544 | var absY = Math.abs(deltaY); |
---|
545 | |
---|
546 | // Check for swipe |
---|
547 | if (absX > absY && (absX > 35) && deltaT < 1000) { |
---|
548 | $el.trigger('swipe', {direction: (deltaX < 0) ? 'left' : 'right'}).unbind('touchmove touchend'); |
---|
549 | } else if (absY > 1) { |
---|
550 | $el.removeClass('active'); |
---|
551 | } |
---|
552 | |
---|
553 | clearTimeout(hoverTimeout); |
---|
554 | } |
---|
555 | |
---|
556 | function touchend(){ |
---|
557 | updateChanges(); |
---|
558 | |
---|
559 | if (deltaY === 0 && deltaX === 0) { |
---|
560 | $el.makeActive(); |
---|
561 | // New approach: |
---|
562 | // Fake the double click? |
---|
563 | // TODO: Try with all click events (no tap) |
---|
564 | // if (deltaT < 40) |
---|
565 | // { |
---|
566 | // setTimeout(function(){ |
---|
567 | // $el.trigger('touchstart') |
---|
568 | // .trigger('touchend'); |
---|
569 | // }, 0); |
---|
570 | // } |
---|
571 | $el.trigger('tap'); |
---|
572 | } else { |
---|
573 | $el.removeClass('active'); |
---|
574 | } |
---|
575 | $el.unbind('touchmove touchend'); |
---|
576 | clearTimeout(hoverTimeout); |
---|
577 | } |
---|
578 | |
---|
579 | function updateChanges(){ |
---|
580 | var first = event.changedTouches[0] || null; |
---|
581 | deltaX = first.pageX - startX; |
---|
582 | deltaY = first.pageY - startY; |
---|
583 | deltaT = (new Date).getTime() - startTime; |
---|
584 | } |
---|
585 | |
---|
586 | } // End touch handler |
---|
587 | |
---|
588 | // Public jQuery Fns |
---|
589 | $.fn.unselect = function(obj) { |
---|
590 | if (obj) { |
---|
591 | obj.removeClass('active'); |
---|
592 | } else { |
---|
593 | $('.active').removeClass('active'); |
---|
594 | } |
---|
595 | } |
---|
596 | $.fn.makeActive = function(){ |
---|
597 | return $(this).addClass('active'); |
---|
598 | } |
---|
599 | $.fn.swipe = function(fn) { |
---|
600 | if ($.isFunction(fn)) |
---|
601 | { |
---|
602 | return this.each(function(i, el){ |
---|
603 | $(el).bind('swipe', fn); |
---|
604 | }); |
---|
605 | } |
---|
606 | } |
---|
607 | $.fn.tap = function(fn){ |
---|
608 | if ($.isFunction(fn)) |
---|
609 | { |
---|
610 | var tapEvent = (jQTSettings.useFastTouch && $.support.touch) ? 'tap' : 'click'; |
---|
611 | return $(this).live(tapEvent, fn); |
---|
612 | } else { |
---|
613 | $(this).trigger('tap'); |
---|
614 | } |
---|
615 | } |
---|
616 | |
---|
617 | publicObj = { |
---|
618 | getOrientation: getOrientation, |
---|
619 | goBack: goBack, |
---|
620 | goTo: goTo, |
---|
621 | addAnimation: addAnimation, |
---|
622 | submitForm: submitForm |
---|
623 | } |
---|
624 | |
---|
625 | return publicObj; |
---|
626 | } |
---|
627 | |
---|
628 | // Extensions directly manipulate the jQTouch object, before it's initialized. |
---|
629 | $.jQTouch.prototype.extensions = []; |
---|
630 | $.jQTouch.addExtension = function(extension){ |
---|
631 | $.jQTouch.prototype.extensions.push(extension); |
---|
632 | } |
---|
633 | |
---|
634 | })(jQuery); |
---|