1 | /**
|
---|
2 | * Copyright (c) 2011 Zauber S.A. <http://www.zaubersoftware.com/>
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | * @author Guido Marucci Blas - [email protected]
|
---|
17 | * @description Adds a handler for a custom event 'taphold' that handles a
|
---|
18 | * tap and hold on touch interfaces.
|
---|
19 | */
|
---|
20 | (function($) {
|
---|
21 | var TAP_AND_HOLD_TRIGGER_TIMER = 1000;
|
---|
22 | var MAX_DISTANCE_ALLOWED_IN_TAP_AND_HOLD_EVENT = 5;
|
---|
23 | var TOUCHSTART = "touchstart";
|
---|
24 | var TOUCHEND = "touchend";
|
---|
25 | var TOUCHMOVE = "touchmove";
|
---|
26 |
|
---|
27 | // For debugging only
|
---|
28 | // var TOUCHSTART = "mousedown";
|
---|
29 | // var TOUCHEND = "mouseup";
|
---|
30 | // var TOUCHMOVE = "mousemove";
|
---|
31 |
|
---|
32 | var tapAndHoldTimer = null;
|
---|
33 |
|
---|
34 | function calculateEuclideanDistance(x1, y1, x2, y2) {
|
---|
35 | var diffX = (x2 - x1);
|
---|
36 | var diffY = (y2 - y1);
|
---|
37 | return Math.sqrt((diffX * diffX) + (diffY * diffY));
|
---|
38 | };
|
---|
39 |
|
---|
40 | function onTouchStart(event) {
|
---|
41 | var e = event.originalEvent;
|
---|
42 |
|
---|
43 | // Only start detector if and only if one finger is over the widget
|
---|
44 | if (!e.touches || (e.targetTouches.length === 1 && e.touches.length === 1)) {
|
---|
45 | startTapAndHoldDetector.call(this, event)
|
---|
46 | var element = $(this);
|
---|
47 | element.bind(TOUCHMOVE, onTouchMove);
|
---|
48 | element.bind(TOUCHEND, onTouchEnd);
|
---|
49 | } else {
|
---|
50 | stopTapAndHoldDetector.call(this);
|
---|
51 | }
|
---|
52 | };
|
---|
53 |
|
---|
54 | function onTouchMove(event) {
|
---|
55 | if (tapAndHoldTimer == null) {
|
---|
56 | return;
|
---|
57 | }
|
---|
58 |
|
---|
59 | var e = event.originalEvent;
|
---|
60 | var x = (e.changedTouches) ? e.changedTouches[0].pageX: e.pageX;
|
---|
61 | var y = (e.changedTouches) ? e.changedTouches[0].pageY: e.pageY;
|
---|
62 |
|
---|
63 | var tapAndHoldPoint = $(this).data("taphold.point");
|
---|
64 | var euclideanDistance = calculateEuclideanDistance(tapAndHoldPoint.x, tapAndHoldPoint.y, x, y);
|
---|
65 |
|
---|
66 | if (euclideanDistance > MAX_DISTANCE_ALLOWED_IN_TAP_AND_HOLD_EVENT) {
|
---|
67 | stopTapAndHoldDetector.call(this);
|
---|
68 | }
|
---|
69 | };
|
---|
70 |
|
---|
71 | function onTouchEnd(event) {
|
---|
72 | stopTapAndHoldDetector.call(this);
|
---|
73 | };
|
---|
74 |
|
---|
75 | function onTapAndHold(event) {
|
---|
76 | clear.call(this);
|
---|
77 | $(this).data("taphold.handler").call(this, event);
|
---|
78 | };
|
---|
79 |
|
---|
80 | function clear() {
|
---|
81 | tapAndHoldTimer = null;
|
---|
82 | $(this).unbind(TOUCHMOVE, onTouchMove);
|
---|
83 | $(this).unbind(TOUCHEND, onTouchEnd);
|
---|
84 | };
|
---|
85 |
|
---|
86 | function startTapAndHoldDetector(event) {
|
---|
87 | if (tapAndHoldTimer != null) {
|
---|
88 | return;
|
---|
89 | }
|
---|
90 | var self = this;
|
---|
91 | tapAndHoldTimer = setTimeout(function(){
|
---|
92 | onTapAndHold.call(self, event)
|
---|
93 | }, TAP_AND_HOLD_TRIGGER_TIMER);
|
---|
94 |
|
---|
95 | // Stores tap x & y
|
---|
96 | var e = event.originalEvent;
|
---|
97 | var tapAndHoldPoint = {};
|
---|
98 | tapAndHoldPoint.x = (e.changedTouches) ? e.changedTouches[0].pageX: e.pageX;
|
---|
99 | tapAndHoldPoint.y = (e.changedTouches) ? e.changedTouches[0].pageY: e.pageY;
|
---|
100 | $(this).data("taphold.point", tapAndHoldPoint);
|
---|
101 | };
|
---|
102 |
|
---|
103 | function stopTapAndHoldDetector() {
|
---|
104 | clearTimeout(tapAndHoldTimer);
|
---|
105 | clear.call(this);
|
---|
106 | };
|
---|
107 |
|
---|
108 | $.event.special["taphold"] = {
|
---|
109 | setup: function() {
|
---|
110 |
|
---|
111 | },
|
---|
112 |
|
---|
113 | add: function(handleObj) {
|
---|
114 | $(this).data("taphold.handler", handleObj.handler);
|
---|
115 | if (handleObj.data) {
|
---|
116 | $(this).bind(TOUCHSTART, handleObj.data, onTouchStart);
|
---|
117 | } else {
|
---|
118 | $(this).bind(TOUCHSTART, onTouchStart);
|
---|
119 | }
|
---|
120 | },
|
---|
121 |
|
---|
122 | remove: function(handleObj) {
|
---|
123 | stopTapAndHoldDetector.call(this);
|
---|
124 | if (handleObj.data) {
|
---|
125 | $(this).unbind(TOUCHSTART, handleObj.data, onTouchStart);
|
---|
126 | } else {
|
---|
127 | $(this).unbind(TOUCHSTART, onTouchStart);
|
---|
128 | }
|
---|
129 | },
|
---|
130 |
|
---|
131 | teardown: function() {
|
---|
132 |
|
---|
133 | }
|
---|
134 | };
|
---|
135 |
|
---|
136 | })(jQuery); |
---|