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