tap.js
(function(global, factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
// 支持AMD ,使用 require.js
define(function() {
return (global.Tap = factory(global, global.document));
});
} else if (typeof exports === 'object') {
// 支持 es6 module
module.exports = factory(global, global.document);
} else {
global.Tap = factory(global, global.document);
}
})(typeof window !== 'undefined' ? window : this, function(window, document) {
"use strict";
function Tap(el) {
this.el = typeof el === "object" ? el : document.getElementById(el);
this.moved = false;
this.startX = 0;
this.startY = 0;
this.hasTouchEventOccured = false;
this.el.addEventListener("touchstart", this, false);
this.el.addEventListener("mousedown", this, false);
}
Tap.prototype.leftButton = function(event) {
// modern & MSIE>=9, FireFox(all)
if ('button' in event) {
return event.buttons === 1;
} else {
return 'which' in event ? event.which === 1 : event.button === 1;
}
}
Tap.prototype.start = function(e) {
if (e.type === 'touchstart') {
this.hasTouchEventOccured = true;
this.el.addEventListener("touchmove", this, false);
this.el.addEventListener("touchend", this, false);
this.el.addEventListener("touchcancel", this, false);
} else if (e.type === 'mousedown' && this.leftButton(e)) {
this.el.addEventListener('mousemove', this, false);
this.el.addEventListener('mouseup', this, false);
}
this.moved = false;
this.startX = e.type === 'touchstart' ? e.touches[0].clientX : e.clientX;
this.startY = e.type === 'touchstart' ? e.touches[0].clientY : e.clientY;
};
Tap.prototype.move = function(e) {
// if finger moves more than 10px flag to cancel
var x = e.type === 'touchmove' ? e.touches[0].clientX : e.clientY;
var y = e.type === 'touchmove' ? e.touches[0].clientY : e.clientY;
if (Math.abs(x - this.startX) > 10 || Math.abs(y - this.startY) > 10) {
this.moved = true;
}
};
Tap.prototype.end = function(e) {
var evt;
this.el.removeEventListener('touchmove', this, false);
this.el.removeEventListener('touchend', this, false);
this.el.removeEventListener('touchcancel', this, false);
this.el.removeEventListener('mouseup', this, false);
this.el.removeEventListener('mousemove', this, false);
if (!this.moved) {
try {
evt = new window.CustomEvent('tap', {
// 创建事件 tap
// 支持冒泡,取消冒泡功能
bubbles: true,
cancelable: true,
})
} catch (e) {
evt = document.createEvent("Event");
evt.initEvent('tap', true, true);
}
}
// 阻止冒泡
e.stopPropagation();
// dispatchEvent returns false if any handler calls preventDefault,
if (!e.target.dispatchEvent(evt)) {
e.preventDefault();
}
};
Tap.prototype.cancel = function() {
this.hasTouchEventOccured = false;
this.moved = false;
this.startX = 0;
this.startY = 0;
};
Tap.prototype.destroy = function() {
this.el.removeEventListener('touchstart', this, false);
this.el.removeEventListener('touchmove', this, false);
this.el.removeEventListener('touchend', this, false);
this.el.removeEventListener('touchcancel', this, false);
this.el.removeEventListener('mousedown', this, false);
this.el.removeEventListener('mouseup', this, false);
this.el.removeEventListener('mousemove', this, false);
};
Tap.prototype.handleEvent = function() {
switch (e.type) {
case 'touchstart':
this.start(e);
break;
case 'touchmove':
this.move(e);
break;
case 'touchend':
this.end(e);
break;
case 'touchcancel':
this.cancel(e);
break;
case 'mousedown':
this.start(e);
break;
case 'mouseup':
this.end(e);
break;
case 'mousemove':
this.move(e);
break;
}
};
return Tap;
});