| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /**
- * Created by 二哲 on 15/12/6.
- */
- /*
- * 不带参数指令
- * v-tap=handler
- * or
- * 带参数指令
- * v-tap=handler($index,el,$event)
- *
- * !!!新增!!!
- * 把tapObj对象注册在原生event对象上
- * event.tapObj拥有6个值
- * pageX,pageY,clientX,clientY,distanceX,distanceY
- * 后面2个分别的手指可能移动的位置(以后可用于拓展手势)
- *
- * */
- ;(function () {
- var vueTap = {};
- var isVue2 = false;
- /** 公用方法开始 **/
- function isPc() {
- var uaInfo = navigator.userAgent;
- var agents = ["Android", "iPhone", "Windows Phone", "iPad", "iPod"];
- var flag = true;
- for ( var i = 0; i < agents.length; i++ ) {
- if (uaInfo.indexOf(agents[i]) > 0) {
- flag = false;
- break;
- }
- }
- return flag;
- }
- function isTap(self) {
- if (isVue2 ? self.disabled : self.el.disabled) {
- return false;
- }
- var tapObj = self.tapObj;
- return self.time < 300 && Math.abs(tapObj.distanceX) < 10 && Math.abs(tapObj.distanceY) < 10;
- }
- function touchstart(e, self) {
- var touches = e.touches[0];
- var tapObj = self.tapObj;
- tapObj.pageX = touches.pageX;
- tapObj.pageY = touches.pageY;
- tapObj.clientX = touches.clientX;
- tapObj.clientY = touches.clientY;
- self.time = +new Date();
- }
- function touchend(e, self) {
- var touches = e.changedTouches[0];
- var tapObj = self.tapObj;
- self.time = +new Date() - self.time;
- tapObj.distanceX = tapObj.pageX - touches.pageX;
- tapObj.distanceY = tapObj.pageY - touches.pageY;
- if (!isTap(self)) return;
- self.handler(e);
- }
- /** 公用方法结束 * */
- var vue1 = {
- isFn: true,
- acceptStatement: true,
- update: function (fn) {
- var self = this;
- self.tapObj = {};
- if (typeof fn !== 'function' && self.el.tagName.toLocaleLowerCase() !== 'a') {
- return console.error('The param of directive "v-tap" must be a function!');
- }
- self.handler = function (e) { //This directive.handler
- e.tapObj = self.tapObj;
- if (self.el.href && !self.modifiers.prevent) {
- return window.location = self.el.href;
- }
- var tagName = e.target.tagName.toLocaleLowerCase();
- if(tagName === 'input' || tagName === 'textarea') {
- return e.target.focus();
- }
- fn.call(self, e);
- };
- if (isPc()) {
- self.el.addEventListener('click', function (e) {
- if (self.el.href && !self.modifiers.prevent) {
- return window.location = self.el.href;
- }
- self.handler.call(self, e);
- }, false);
- } else {
- self.el.addEventListener('touchstart', function (e) {
- if (self.modifiers.stop)
- e.stopPropagation();
- if (self.modifiers.prevent)
- e.preventDefault();
- touchstart(e, self);
- }, false);
- self.el.addEventListener('touchend', function (e) {
- try {
- Object.defineProperty(e, 'currentTarget', {// 重写currentTarget对象 与jq相同
- value: self.el,
- writable: true,
- enumerable: true,
- configurable: true
- })
- } catch (e) {
- // ios 7下对 e.currentTarget 用defineProperty会报错。
- // 报“TypeError:Attempting to configurable attribute of unconfigurable property”错误
- // 在catch里重写
- console.error(e.message)
- e.currentTarget = self.el
- }
- e.preventDefault();
- return touchend(e, self);
- }, false);
- }
- }
- };
- var vue2 = {
- bind: function (el, binding) {
- el.tapObj = {};
- el.handler = function (e,isPc) { //This directive.handler
- var value = binding.value;
- if (!value && el.href && !binding.modifiers.prevent) {
- return window.location = el.href;
- }
- value.event = e;
- var tagName = value.event.target.tagName.toLocaleLowerCase();
- !isPc ? value.tapObj = el.tapObj : null;
- if(tagName === 'input' || tagName === 'textarea') {
- return value.event.target.focus();
- }
- value.methods.call(this, value);
- };
- if (isPc()) {
- el.addEventListener('click', function (e) {
- if (binding.modifiers.stop)
- e.stopPropagation();
- if (binding.modifiers.prevent)
- e.preventDefault();
- el.handler(e, true)
- }, false);
- } else {
- el.addEventListener('touchstart', function (e) {
- if (binding.modifiers.stop)
- e.stopPropagation();
- if (binding.modifiers.prevent)
- e.preventDefault();
- touchstart(e, el);
- }, false);
- el.addEventListener('touchend', function (e) {
- try {
- Object.defineProperty(e, 'currentTarget', {// 重写currentTarget对象 与jq相同
- value: el,
- writable: true,
- enumerable: true,
- configurable: true
- })
- } catch (e) {
- // ios 7下对 e.currentTarget 用defineProperty会报错。
- // 报“TypeError:Attempting to configurable attribute of unconfigurable property”错误
- // 在catch里重写
- console.error(e.message)
- e.currentTarget = el
- }
- e.preventDefault();
- return touchend(e, el);
- }, false);
- }
- },
- componentUpdated : function(el,binding) {
- el.tapObj = {};
- el.handler = function (e,isPc) { //This directive.handler
- var value = binding.value;
- if (!value && el.href && !binding.modifiers.prevent) {
- return window.location = el.href;
- }
- value.event = e;
- !isPc ? value.tapObj = el.tapObj : null;
- value.methods.call(this, value);
- };
- },
- unbind: function (el) {
- // 卸载,别说了都是泪
- el.handler = function () {};
- }
- };
- vueTap.install = function (Vue) {
- if (Vue.version.substr(0, 1) > 1) {
- isVue2 = true;
- }
- Vue.directive('tap', isVue2 ? vue2 : vue1);
- };
- vueTap.version = '3.0.3';
- if (typeof exports == "object") {
- module.exports = vueTap;
- } else if (typeof define == "function" && define.amd) {
- define([], function () {
- return vueTap
- })
- } else if (window.Vue) {
- window.vueTap = vueTap;
- Vue.use(vueTap);
- }
- })();
|