@@ 831-1013 (lines=183) @@ | ||
828 | // https://raw.github.com/madrobby/zepto/master/src/touch.js |
|
829 | // Zepto.js may be freely distributed under the MIT license. |
|
830 | ||
831 | ;(function($){ |
|
832 | ||
833 | if ($.fn.swipeLeft) { |
|
834 | return; |
|
835 | } |
|
836 | ||
837 | ||
838 | var touch = {}, touchTimeout, tapTimeout, swipeTimeout, longTapTimeout, longTapDelay = 750, gesture; |
|
839 | var hasTouchEvents = 'ontouchstart' in window, |
|
840 | hasPointerEvents = window.PointerEvent, |
|
841 | hasTouch = hasTouchEvents |
|
842 | || window.DocumentTouch && document instanceof DocumentTouch |
|
843 | || navigator.msPointerEnabled && navigator.msMaxTouchPoints > 0 // IE 10 |
|
844 | || navigator.pointerEnabled && navigator.maxTouchPoints > 0; // IE >=11 |
|
845 | ||
846 | function swipeDirection(x1, x2, y1, y2) { |
|
847 | return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down'); |
|
848 | } |
|
849 | ||
850 | function longTap() { |
|
851 | longTapTimeout = null; |
|
852 | if (touch.last) { |
|
853 | if ( touch.el !== undefined ) touch.el.trigger('longTap'); |
|
854 | touch = {}; |
|
855 | } |
|
856 | } |
|
857 | ||
858 | function cancelLongTap() { |
|
859 | if (longTapTimeout) clearTimeout(longTapTimeout); |
|
860 | longTapTimeout = null; |
|
861 | } |
|
862 | ||
863 | function cancelAll() { |
|
864 | if (touchTimeout) clearTimeout(touchTimeout); |
|
865 | if (tapTimeout) clearTimeout(tapTimeout); |
|
866 | if (swipeTimeout) clearTimeout(swipeTimeout); |
|
867 | if (longTapTimeout) clearTimeout(longTapTimeout); |
|
868 | touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null; |
|
869 | touch = {}; |
|
870 | } |
|
871 | ||
872 | function isPrimaryTouch(event){ |
|
873 | return event.pointerType == event.MSPOINTER_TYPE_TOUCH && event.isPrimary; |
|
874 | } |
|
875 | ||
876 | $(function(){ |
|
877 | var now, delta, deltaX = 0, deltaY = 0, firstTouch; |
|
878 | ||
879 | if ('MSGesture' in window) { |
|
880 | gesture = new MSGesture(); |
|
881 | gesture.target = document.body; |
|
882 | } |
|
883 | ||
884 | $(document) |
|
885 | .on('MSGestureEnd gestureend', function(e){ |
|
886 | ||
887 | var swipeDirectionFromVelocity = e.originalEvent.velocityX > 1 ? 'Right' : e.originalEvent.velocityX < -1 ? 'Left' : e.originalEvent.velocityY > 1 ? 'Down' : e.originalEvent.velocityY < -1 ? 'Up' : null; |
|
888 | ||
889 | if (swipeDirectionFromVelocity && touch.el !== undefined) { |
|
890 | touch.el.trigger('swipe'); |
|
891 | touch.el.trigger('swipe'+ swipeDirectionFromVelocity); |
|
892 | } |
|
893 | }) |
|
894 | // MSPointerDown: for IE10 |
|
895 | // pointerdown: for IE11 |
|
896 | .on('touchstart MSPointerDown pointerdown', function(e){ |
|
897 | ||
898 | if(e.type == 'MSPointerDown' && !isPrimaryTouch(e.originalEvent)) return; |
|
899 | ||
900 | firstTouch = (e.type == 'MSPointerDown' || e.type == 'pointerdown') ? e : e.originalEvent.touches[0]; |
|
901 | ||
902 | now = Date.now(); |
|
903 | delta = now - (touch.last || now); |
|
904 | touch.el = $('tagName' in firstTouch.target ? firstTouch.target : firstTouch.target.parentNode); |
|
905 | ||
906 | if(touchTimeout) clearTimeout(touchTimeout); |
|
907 | ||
908 | touch.x1 = firstTouch.pageX; |
|
909 | touch.y1 = firstTouch.pageY; |
|
910 | ||
911 | if (delta > 0 && delta <= 250) touch.isDoubleTap = true; |
|
912 | ||
913 | touch.last = now; |
|
914 | longTapTimeout = setTimeout(longTap, longTapDelay); |
|
915 | ||
916 | // adds the current touch contact for IE gesture recognition |
|
917 | if (e.originalEvent && e.originalEvent.pointerId && gesture && ( e.type == 'MSPointerDown' || e.type == 'pointerdown' || e.type == 'touchstart' ) ) { |
|
918 | gesture.addPointer(e.originalEvent.pointerId); |
|
919 | } |
|
920 | ||
921 | }) |
|
922 | // MSPointerMove: for IE10 |
|
923 | // pointermove: for IE11 |
|
924 | .on('touchmove MSPointerMove pointermove', function(e){ |
|
925 | ||
926 | if (e.type == 'MSPointerMove' && !isPrimaryTouch(e.originalEvent)) return; |
|
927 | ||
928 | firstTouch = (e.type == 'MSPointerMove' || e.type == 'pointermove') ? e : e.originalEvent.touches[0]; |
|
929 | ||
930 | cancelLongTap(); |
|
931 | touch.x2 = firstTouch.pageX; |
|
932 | touch.y2 = firstTouch.pageY; |
|
933 | ||
934 | deltaX += Math.abs(touch.x1 - touch.x2); |
|
935 | deltaY += Math.abs(touch.y1 - touch.y2); |
|
936 | }) |
|
937 | // MSPointerUp: for IE10 |
|
938 | // pointerup: for IE11 |
|
939 | .on('touchend MSPointerUp pointerup', function(e){ |
|
940 | ||
941 | if (e.type == 'MSPointerUp' && !isPrimaryTouch(e.originalEvent)) return; |
|
942 | ||
943 | cancelLongTap(); |
|
944 | ||
945 | // swipe |
|
946 | if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)){ |
|
947 | ||
948 | swipeTimeout = setTimeout(function() { |
|
949 | if ( touch.el !== undefined ) { |
|
950 | touch.el.trigger('swipe'); |
|
951 | touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2))); |
|
952 | } |
|
953 | touch = {}; |
|
954 | }, 0); |
|
955 | ||
956 | // normal tap |
|
957 | } else if ('last' in touch) { |
|
958 | ||
959 | // don't fire tap when delta position changed by more than 30 pixels, |
|
960 | // for instance when moving to a point and back to origin |
|
961 | if (isNaN(deltaX) || (deltaX < 30 && deltaY < 30)) { |
|
962 | // delay by one tick so we can cancel the 'tap' event if 'scroll' fires |
|
963 | // ('tap' fires before 'scroll') |
|
964 | tapTimeout = setTimeout(function() { |
|
965 | ||
966 | // trigger universal 'tap' with the option to cancelTouch() |
|
967 | // (cancelTouch cancels processing of single vs double taps for faster 'tap' response) |
|
968 | var event = $.Event('tap'); |
|
969 | event.cancelTouch = cancelAll; |
|
970 | if ( touch.el !== undefined ) touch.el.trigger(event); |
|
971 | ||
972 | // trigger double tap immediately |
|
973 | if (touch.isDoubleTap) { |
|
974 | if ( touch.el !== undefined ) touch.el.trigger('doubleTap'); |
|
975 | touch = {}; |
|
976 | } |
|
977 | ||
978 | // trigger single tap after 250ms of inactivity |
|
979 | else { |
|
980 | touchTimeout = setTimeout(function(){ |
|
981 | touchTimeout = null; |
|
982 | if ( touch.el !== undefined ) touch.el.trigger('singleTap'); |
|
983 | touch = {}; |
|
984 | }, 250); |
|
985 | } |
|
986 | }, 0); |
|
987 | } else { |
|
988 | touch = {}; |
|
989 | } |
|
990 | deltaX = deltaY = 0; |
|
991 | } |
|
992 | }) |
|
993 | // when the browser window loses focus, |
|
994 | // for example when a modal dialog is shown, |
|
995 | // cancel all ongoing events |
|
996 | .on('touchcancel MSPointerCancel pointercancel', function(e){ |
|
997 | ||
998 | // Ignore pointercancel if the event supports touch events, to prevent pointercancel in swipe gesture |
|
999 | if ((e.type == 'touchcancel' && hasTouchEvents && hasTouch) || (!hasTouchEvents && e.type == 'pointercancel' && hasPointerEvents)) { |
|
1000 | cancelAll(); |
|
1001 | } |
|
1002 | ||
1003 | }); |
|
1004 | ||
1005 | // scrolling the window indicates intention of the user |
|
1006 | // to scroll, not tap or swipe, so cancel all ongoing events |
|
1007 | $(window).on('scroll', cancelAll); |
|
1008 | }); |
|
1009 | ||
1010 | ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){ |
|
1011 | $.fn[eventName] = function(callback){ return $(this).on(eventName, callback); }; |
|
1012 | }); |
|
1013 | })(jQuery); |
|
1014 | ||
1015 | (function(UI) { |
|
1016 |
@@ 6-188 (lines=183) @@ | ||
3 | // https://raw.github.com/madrobby/zepto/master/src/touch.js |
|
4 | // Zepto.js may be freely distributed under the MIT license. |
|
5 | ||
6 | ;(function($){ |
|
7 | ||
8 | if ($.fn.swipeLeft) { |
|
9 | return; |
|
10 | } |
|
11 | ||
12 | ||
13 | var touch = {}, touchTimeout, tapTimeout, swipeTimeout, longTapTimeout, longTapDelay = 750, gesture; |
|
14 | var hasTouchEvents = 'ontouchstart' in window, |
|
15 | hasPointerEvents = window.PointerEvent, |
|
16 | hasTouch = hasTouchEvents |
|
17 | || window.DocumentTouch && document instanceof DocumentTouch |
|
18 | || navigator.msPointerEnabled && navigator.msMaxTouchPoints > 0 // IE 10 |
|
19 | || navigator.pointerEnabled && navigator.maxTouchPoints > 0; // IE >=11 |
|
20 | ||
21 | function swipeDirection(x1, x2, y1, y2) { |
|
22 | return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down'); |
|
23 | } |
|
24 | ||
25 | function longTap() { |
|
26 | longTapTimeout = null; |
|
27 | if (touch.last) { |
|
28 | if ( touch.el !== undefined ) touch.el.trigger('longTap'); |
|
29 | touch = {}; |
|
30 | } |
|
31 | } |
|
32 | ||
33 | function cancelLongTap() { |
|
34 | if (longTapTimeout) clearTimeout(longTapTimeout); |
|
35 | longTapTimeout = null; |
|
36 | } |
|
37 | ||
38 | function cancelAll() { |
|
39 | if (touchTimeout) clearTimeout(touchTimeout); |
|
40 | if (tapTimeout) clearTimeout(tapTimeout); |
|
41 | if (swipeTimeout) clearTimeout(swipeTimeout); |
|
42 | if (longTapTimeout) clearTimeout(longTapTimeout); |
|
43 | touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null; |
|
44 | touch = {}; |
|
45 | } |
|
46 | ||
47 | function isPrimaryTouch(event){ |
|
48 | return event.pointerType == event.MSPOINTER_TYPE_TOUCH && event.isPrimary; |
|
49 | } |
|
50 | ||
51 | $(function(){ |
|
52 | var now, delta, deltaX = 0, deltaY = 0, firstTouch; |
|
53 | ||
54 | if ('MSGesture' in window) { |
|
55 | gesture = new MSGesture(); |
|
56 | gesture.target = document.body; |
|
57 | } |
|
58 | ||
59 | $(document) |
|
60 | .on('MSGestureEnd gestureend', function(e){ |
|
61 | ||
62 | var swipeDirectionFromVelocity = e.originalEvent.velocityX > 1 ? 'Right' : e.originalEvent.velocityX < -1 ? 'Left' : e.originalEvent.velocityY > 1 ? 'Down' : e.originalEvent.velocityY < -1 ? 'Up' : null; |
|
63 | ||
64 | if (swipeDirectionFromVelocity && touch.el !== undefined) { |
|
65 | touch.el.trigger('swipe'); |
|
66 | touch.el.trigger('swipe'+ swipeDirectionFromVelocity); |
|
67 | } |
|
68 | }) |
|
69 | // MSPointerDown: for IE10 |
|
70 | // pointerdown: for IE11 |
|
71 | .on('touchstart MSPointerDown pointerdown', function(e){ |
|
72 | ||
73 | if(e.type == 'MSPointerDown' && !isPrimaryTouch(e.originalEvent)) return; |
|
74 | ||
75 | firstTouch = (e.type == 'MSPointerDown' || e.type == 'pointerdown') ? e : e.originalEvent.touches[0]; |
|
76 | ||
77 | now = Date.now(); |
|
78 | delta = now - (touch.last || now); |
|
79 | touch.el = $('tagName' in firstTouch.target ? firstTouch.target : firstTouch.target.parentNode); |
|
80 | ||
81 | if(touchTimeout) clearTimeout(touchTimeout); |
|
82 | ||
83 | touch.x1 = firstTouch.pageX; |
|
84 | touch.y1 = firstTouch.pageY; |
|
85 | ||
86 | if (delta > 0 && delta <= 250) touch.isDoubleTap = true; |
|
87 | ||
88 | touch.last = now; |
|
89 | longTapTimeout = setTimeout(longTap, longTapDelay); |
|
90 | ||
91 | // adds the current touch contact for IE gesture recognition |
|
92 | if (e.originalEvent && e.originalEvent.pointerId && gesture && ( e.type == 'MSPointerDown' || e.type == 'pointerdown' || e.type == 'touchstart' ) ) { |
|
93 | gesture.addPointer(e.originalEvent.pointerId); |
|
94 | } |
|
95 | ||
96 | }) |
|
97 | // MSPointerMove: for IE10 |
|
98 | // pointermove: for IE11 |
|
99 | .on('touchmove MSPointerMove pointermove', function(e){ |
|
100 | ||
101 | if (e.type == 'MSPointerMove' && !isPrimaryTouch(e.originalEvent)) return; |
|
102 | ||
103 | firstTouch = (e.type == 'MSPointerMove' || e.type == 'pointermove') ? e : e.originalEvent.touches[0]; |
|
104 | ||
105 | cancelLongTap(); |
|
106 | touch.x2 = firstTouch.pageX; |
|
107 | touch.y2 = firstTouch.pageY; |
|
108 | ||
109 | deltaX += Math.abs(touch.x1 - touch.x2); |
|
110 | deltaY += Math.abs(touch.y1 - touch.y2); |
|
111 | }) |
|
112 | // MSPointerUp: for IE10 |
|
113 | // pointerup: for IE11 |
|
114 | .on('touchend MSPointerUp pointerup', function(e){ |
|
115 | ||
116 | if (e.type == 'MSPointerUp' && !isPrimaryTouch(e.originalEvent)) return; |
|
117 | ||
118 | cancelLongTap(); |
|
119 | ||
120 | // swipe |
|
121 | if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)){ |
|
122 | ||
123 | swipeTimeout = setTimeout(function() { |
|
124 | if ( touch.el !== undefined ) { |
|
125 | touch.el.trigger('swipe'); |
|
126 | touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2))); |
|
127 | } |
|
128 | touch = {}; |
|
129 | }, 0); |
|
130 | ||
131 | // normal tap |
|
132 | } else if ('last' in touch) { |
|
133 | ||
134 | // don't fire tap when delta position changed by more than 30 pixels, |
|
135 | // for instance when moving to a point and back to origin |
|
136 | if (isNaN(deltaX) || (deltaX < 30 && deltaY < 30)) { |
|
137 | // delay by one tick so we can cancel the 'tap' event if 'scroll' fires |
|
138 | // ('tap' fires before 'scroll') |
|
139 | tapTimeout = setTimeout(function() { |
|
140 | ||
141 | // trigger universal 'tap' with the option to cancelTouch() |
|
142 | // (cancelTouch cancels processing of single vs double taps for faster 'tap' response) |
|
143 | var event = $.Event('tap'); |
|
144 | event.cancelTouch = cancelAll; |
|
145 | if ( touch.el !== undefined ) touch.el.trigger(event); |
|
146 | ||
147 | // trigger double tap immediately |
|
148 | if (touch.isDoubleTap) { |
|
149 | if ( touch.el !== undefined ) touch.el.trigger('doubleTap'); |
|
150 | touch = {}; |
|
151 | } |
|
152 | ||
153 | // trigger single tap after 250ms of inactivity |
|
154 | else { |
|
155 | touchTimeout = setTimeout(function(){ |
|
156 | touchTimeout = null; |
|
157 | if ( touch.el !== undefined ) touch.el.trigger('singleTap'); |
|
158 | touch = {}; |
|
159 | }, 250); |
|
160 | } |
|
161 | }, 0); |
|
162 | } else { |
|
163 | touch = {}; |
|
164 | } |
|
165 | deltaX = deltaY = 0; |
|
166 | } |
|
167 | }) |
|
168 | // when the browser window loses focus, |
|
169 | // for example when a modal dialog is shown, |
|
170 | // cancel all ongoing events |
|
171 | .on('touchcancel MSPointerCancel pointercancel', function(e){ |
|
172 | ||
173 | // Ignore pointercancel if the event supports touch events, to prevent pointercancel in swipe gesture |
|
174 | if ((e.type == 'touchcancel' && hasTouchEvents && hasTouch) || (!hasTouchEvents && e.type == 'pointercancel' && hasPointerEvents)) { |
|
175 | cancelAll(); |
|
176 | } |
|
177 | ||
178 | }); |
|
179 | ||
180 | // scrolling the window indicates intention of the user |
|
181 | // to scroll, not tap or swipe, so cancel all ongoing events |
|
182 | $(window).on('scroll', cancelAll); |
|
183 | }); |
|
184 | ||
185 | ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){ |
|
186 | $.fn[eventName] = function(callback){ return $(this).on(eventName, callback); }; |
|
187 | }); |
|
188 | })(jQuery); |
|
189 |