1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| function FastClick(layer, options) { var oldOnClick; options = options || {};
this.trackingClick = false; // 当前的点击是否是被标记的 this.trackingClickStart = 0; // 点击被标记时的时间戳 this.targetElement = null; // 被标记点击的元素 this.touchStartX = 0; // touch开始时的横坐标值 this.touchStartY = 0; // touch开始时的纵坐标值 this.lastTouchIdentifier = 0; // 最后一次touch的id, 为Touch.identifier. this.touchBoundary = options.touchBoundary || 10; // 标识 Touchmove 的分界线, 如超过后则取消触发点击.
this.layer = layer; // 绑定FastClick的layer. this.tapDelay = options.tapDelay || 200; // 判断为 tap(touchstart 和 touchend) 事件之间最小时间间隔 this.tapTimeout = options.tapTimeout || 700; // 判断为 tap 的最大时间间隔
if (FastClick.notNeeded(layer)) { return; }
// 部分老版本安卓没有 Function.prototype.bind function bind(method, context) { return function() { return method.apply(context, arguments); }; }
// 添加实例的几个事件方法 var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel']; var context = this; for (var i = 0, l = methods.length; i < l; i++) { context[methods[i]] = bind(context[methods[i]], context); }
// 更具需要来设置事件 if (deviceIsAndroid) { layer.addEventListener('mouseover', this.onMouse, true); layer.addEventListener('mousedown', this.onMouse, true); layer.addEventListener('mouseup', this.onMouse, true); }
layer.addEventListener('click', this.onClick, true); layer.addEventListener('touchstart', this.onTouchStart, false); layer.addEventListener('touchmove', this.onTouchMove, false); layer.addEventListener('touchend', this.onTouchEnd, false); layer.addEventListener('touchcancel', this.onTouchCancel, false);
// 对于浏览器不支持事件 stopImmediatePropagation的hack一下 (e.g. Android 2) // 这是 FastClick 通常如何阻止的形式 点击事件在冒泡到 FastClick layer 注册的回调方法之前就被取消。
if (!Event.prototype.stopImmediatePropagation) { layer.removeEventListener = function(type, callback, capture) { var rmv = Node.prototype.removeEventListener; if (type === 'click') { rmv.call(layer, type, callback.hijacked || callback, capture); } else { rmv.call(layer, type, callback, capture); } };
// 重写layer的绑定事件方法 单独处理click layer.addEventListener = function(type, callback, capture) { var adv = Node.prototype.addEventListener; if (type === 'click') { adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) { if (!event.propagationStopped) { callback(event); } }), capture); } else { adv.call(layer, type, callback, capture); } }; }
// 如果事件句柄已经被绑定在元素的 onclick 属性上, 会在 FastClick的onClick事件之前触发 // 通过创建用户定义事件句柄函数,将其添加到监听中来解决 if (typeof layer.onclick === 'function') {
// 低于3.2的Android浏览器需要将 layer.onclick 指向新的引用 // 如果直接传递,会有有一定问题 oldOnClick = layer.onclick; layer.addEventListener('click', function(event) { oldOnClick(event); }, false); layer.onclick = null; } }
|