[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /* 2 YUI 3.17.2 (build 9c3c78e) 3 Copyright 2014 Yahoo! Inc. All rights reserved. 4 Licensed under the BSD License. 5 http://yuilibrary.com/license/ 6 */ 7 8 YUI.add('event-tap', function (Y, NAME) { 9 10 /** 11 The tap module provides a gesture events, "tap", which normalizes user interactions 12 across touch and mouse or pointer based input devices. This can be used by application developers 13 to build input device agnostic components which behave the same in response to either touch or mouse based 14 interaction. 15 16 'tap' is like a touchscreen 'click', only it requires much less finger-down time since it listens to touch events, 17 but reverts to mouse events if touch is not supported. 18 19 @example 20 21 YUI().use('event-tap', function (Y) { 22 Y.one('#my-button').on('tap', function (e) { 23 Y.log('Button was tapped on'); 24 }); 25 }); 26 27 @module event 28 @submodule event-tap 29 @author Andres Garza, matuzak and tilo mitra 30 @since 3.7.0 31 32 */ 33 var doc = Y.config.doc, 34 GESTURE_MAP = Y.Event._GESTURE_MAP, 35 EVT_START = GESTURE_MAP.start, 36 EVT_TAP = 'tap', 37 POINTER_EVENT_TEST = /pointer/i, 38 39 HANDLES = { 40 START: 'Y_TAP_ON_START_HANDLE', 41 END: 'Y_TAP_ON_END_HANDLE', 42 CANCEL: 'Y_TAP_ON_CANCEL_HANDLE' 43 }; 44 45 function detachHandles(subscription, handles) { 46 handles = handles || Y.Object.values(HANDLES); 47 48 Y.Array.each(handles, function (item) { 49 var handle = subscription[item]; 50 if (handle) { 51 handle.detach(); 52 subscription[item] = null; 53 } 54 }); 55 56 } 57 58 59 /** 60 Sets up a "tap" event, that is fired on touch devices in response to a tap event (finger down, finder up). 61 This event can be used instead of listening for click events which have a 500ms delay on most touch devices. 62 This event can also be listened for using node.delegate(). 63 64 @event tap 65 @param type {string} "tap" 66 @param fn {function} The method the event invokes. It receives the event facade of the underlying DOM event. 67 @for Event 68 @return {EventHandle} the detach handle 69 */ 70 Y.Event.define(EVT_TAP, { 71 publishConfig: { 72 preventedFn: function (e) { 73 var sub = e.target.once('click', function (click) { 74 click.preventDefault(); 75 }); 76 77 // Make sure to detach the subscription during the next event loop 78 // so this doesn't `preventDefault()` on the wrong click event. 79 setTimeout(function () { 80 sub.detach(); 81 //Setting this to `0` causes the detachment to occur before the click 82 //comes in on Android 4.0.3-4.0.4. 100ms seems to be a reliable number here 83 //that works across the board. 84 }, 100); 85 } 86 }, 87 88 processArgs: function (args, isDelegate) { 89 90 //if we return for the delegate use case, then the `filter` argument 91 //returns undefined, and we have to get the filter from sub._extra[0] (ugly) 92 93 if (!isDelegate) { 94 var extra = args[3]; 95 // remove the extra arguments from the array as specified by 96 // http://yuilibrary.com/yui/docs/event/synths.html 97 args.splice(3,1); 98 return extra; 99 } 100 }, 101 /** 102 This function should set up the node that will eventually fire the event. 103 104 Usage: 105 106 node.on('tap', function (e) { 107 Y.log('the node was tapped on'); 108 }); 109 110 @method on 111 @param {Node} node 112 @param {Array} subscription 113 @param {Boolean} notifier 114 @public 115 @static 116 **/ 117 on: function (node, subscription, notifier) { 118 subscription[HANDLES.START] = node.on(EVT_START, this._start, this, node, subscription, notifier); 119 }, 120 121 /** 122 Detaches all event subscriptions set up by the event-tap module 123 124 @method detach 125 @param {Node} node 126 @param {Array} subscription 127 @param {Boolean} notifier 128 @public 129 @static 130 **/ 131 detach: function (node, subscription, notifier) { 132 detachHandles(subscription); 133 }, 134 135 /** 136 Event delegation for the 'tap' event. The delegated event will use a 137 supplied selector or filtering function to test if the event references at least one 138 node that should trigger the subscription callback. 139 140 Usage: 141 142 node.delegate('tap', function (e) { 143 Y.log('li a inside node was tapped.'); 144 }, 'li a'); 145 146 @method delegate 147 @param {Node} node 148 @param {Array} subscription 149 @param {Boolean} notifier 150 @param {String | Function} filter 151 @public 152 @static 153 **/ 154 delegate: function (node, subscription, notifier, filter) { 155 subscription[HANDLES.START] = Y.delegate(EVT_START, function (e) { 156 this._start(e, node, subscription, notifier, true); 157 }, node, filter, this); 158 }, 159 160 /** 161 Detaches the delegated event subscriptions set up by the event-tap module. 162 Only used if you use node.delegate(...) instead of node.on(...); 163 164 @method detachDelegate 165 @param {Node} node 166 @param {Array} subscription 167 @param {Boolean} notifier 168 @public 169 @static 170 **/ 171 detachDelegate: function (node, subscription, notifier) { 172 detachHandles(subscription); 173 }, 174 175 /** 176 Called when the monitor(s) are tapped on, either through touchstart or mousedown. 177 178 @method _start 179 @param {DOMEventFacade} event 180 @param {Node} node 181 @param {Array} subscription 182 @param {Boolean} notifier 183 @param {Boolean} delegate 184 @protected 185 @static 186 **/ 187 _start: function (event, node, subscription, notifier, delegate) { 188 189 var context = { 190 canceled: false, 191 eventType: event.type 192 }, 193 preventMouse = subscription.preventMouse || false; 194 195 //move ways to quit early to the top. 196 // no right clicks 197 if (event.button && event.button === 3) { 198 return; 199 } 200 201 // for now just support a 1 finger count (later enhance via config) 202 if (event.touches && event.touches.length !== 1) { 203 return; 204 } 205 206 context.node = delegate ? event.currentTarget : node; 207 208 //There is a double check in here to support event simulation tests, in which 209 //event.touches can be undefined when simulating 'touchstart' on touch devices. 210 if (event.touches) { 211 context.startXY = [ event.touches[0].pageX, event.touches[0].pageY ]; 212 } 213 else { 214 context.startXY = [ event.pageX, event.pageY ]; 215 } 216 217 //If `onTouchStart()` was called by a touch event, set up touch event subscriptions. 218 //Otherwise, set up mouse/pointer event event subscriptions. 219 if (event.touches) { 220 221 subscription[HANDLES.END] = node.once('touchend', this._end, this, node, subscription, notifier, delegate, context); 222 subscription[HANDLES.CANCEL] = node.once('touchcancel', this.detach, this, node, subscription, notifier, delegate, context); 223 224 //Since this is a touch* event, there will be corresponding mouse events 225 //that will be fired. We don't want these events to get picked up and fire 226 //another `tap` event, so we'll set this variable to `true`. 227 subscription.preventMouse = true; 228 } 229 230 //Only add these listeners if preventMouse is `false` 231 //ie: not when touch events have already been subscribed to 232 else if (context.eventType.indexOf('mouse') !== -1 && !preventMouse) { 233 subscription[HANDLES.END] = node.once('mouseup', this._end, this, node, subscription, notifier, delegate, context); 234 subscription[HANDLES.CANCEL] = node.once('mousecancel', this.detach, this, node, subscription, notifier, delegate, context); 235 } 236 237 //If a mouse event comes in after a touch event, it will go in here and 238 //reset preventMouse to `true`. 239 //If a mouse event comes in without a prior touch event, preventMouse will be 240 //false in any case, so this block doesn't do anything. 241 else if (context.eventType.indexOf('mouse') !== -1 && preventMouse) { 242 subscription.preventMouse = false; 243 } 244 245 else if (POINTER_EVENT_TEST.test(context.eventType)) { 246 subscription[HANDLES.END] = node.once(GESTURE_MAP.end, this._end, this, node, subscription, notifier, delegate, context); 247 subscription[HANDLES.CANCEL] = node.once(GESTURE_MAP.cancel, this.detach, this, node, subscription, notifier, delegate, context); 248 } 249 250 }, 251 252 253 /** 254 Called when the monitor(s) fires a touchend event (or the mouse equivalent). 255 This method fires the 'tap' event if certain requirements are met. 256 257 @method _end 258 @param {DOMEventFacade} event 259 @param {Node} node 260 @param {Array} subscription 261 @param {Boolean} notifier 262 @param {Boolean} delegate 263 @param {Object} context 264 @protected 265 @static 266 **/ 267 _end: function (event, node, subscription, notifier, delegate, context) { 268 var startXY = context.startXY, 269 endXY, 270 clientXY, 271 sensitivity = 15; 272 273 if (subscription._extra && subscription._extra.sensitivity >= 0) { 274 sensitivity = subscription._extra.sensitivity; 275 } 276 277 //There is a double check in here to support event simulation tests, in which 278 //event.touches can be undefined when simulating 'touchstart' on touch devices. 279 if (event.changedTouches) { 280 endXY = [ event.changedTouches[0].pageX, event.changedTouches[0].pageY ]; 281 clientXY = [event.changedTouches[0].clientX, event.changedTouches[0].clientY]; 282 } 283 else { 284 endXY = [ event.pageX, event.pageY ]; 285 clientXY = [event.clientX, event.clientY]; 286 } 287 288 // make sure mouse didn't move 289 if (Math.abs(endXY[0] - startXY[0]) <= sensitivity && Math.abs(endXY[1] - startXY[1]) <= sensitivity) { 290 291 event.type = EVT_TAP; 292 event.pageX = endXY[0]; 293 event.pageY = endXY[1]; 294 event.clientX = clientXY[0]; 295 event.clientY = clientXY[1]; 296 event.currentTarget = context.node; 297 298 notifier.fire(event); 299 } 300 301 detachHandles(subscription, [HANDLES.END, HANDLES.CANCEL]); 302 } 303 }); 304 305 306 }, '3.17.2', {"requires": ["node-base", "event-base", "event-touch", "event-synthetic"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |