UNPKG

migi

Version:

A JavaScript MVVM on JSX

171 lines (150 loc) 4.09 kB
define(function(require, exports, module){'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = function (vd, name, cb, listener) { if (!hasInitGlobal) { hasInitGlobal = true; initGlobal(); } listener.push(['touchstart', onTouchStart]); var elem = vd.element; elem.addEventListener('touchstart', onTouchStart); function onTouchStart(e) { // 有可能组件内父子多个使用了手势,冒泡触发了多个 if (touch.first) { touchList.push({ vd: vd, name: name, cb: cb }); return; } firstTouch = e.touches[0]; if (e.touches && e.touches.length === 1 && touch.x2) { // Clear out touch movement data if we have it sticking around // This can occur if touchcancel doesn't fire due to preventDefault, etc. touch.x2 = undefined; touch.y2 = undefined; } touch = { vd: vd, name: name, cb: cb, first: true, x1: firstTouch.pageX, y1: firstTouch.pageY }; lastTouch = touch; now = Date.now(); delta = now - lastTime; lastTime = now; if (delta > 0 && delta < 250) { touch.isDoubleTap = true; } } }; /** * Thanks to zepto-touch.js * https://github.com/madrobby/zepto/blob/master/src/touch.js */ var touchList = []; var touch = {}; var lastTouch; var tapTimeout; var swipeTimeout; var longTapDelay = 750; var lastTime = 0; var now; var delta; var deltaX = 0; var deltaY = 0; var firstTouch; function swipeDirection(x1, x2, y1, y2) { return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? x1 - x2 > 0 ? 'left' : 'right' : y1 - y2 > 0 ? 'up' : 'down'; } function cancelAll() { if (tapTimeout) { clearTimeout(tapTimeout); } if (swipeTimeout) { clearTimeout(swipeTimeout); } tapTimeout = swipeTimeout = null; touch = {}; touchList = []; } var hasInitGlobal; function initGlobal() { document.addEventListener('touchmove', onTouchMove, true); document.addEventListener('touchend', onTouchEnd, true); document.addEventListener('touchcancel', cancelAll, true); window.addEventListener('scroll', cancelAll); window.addEventListener('blur', cancelAll); } function onTouchMove(e) { if (!touch.vd) { return; } firstTouch = e.touches[0]; touch.x2 = firstTouch.pageX; touch.y2 = firstTouch.pageY; deltaX += Math.abs(touch.x1 - touch.x2); deltaY += Math.abs(touch.y1 - touch.y2); } function onTouchEnd(e) { if (!touch.vd) { return; } // swipe if (touch.x2 && Math.abs(touch.x1 - touch.x2) > 30 || touch.y2 && Math.abs(touch.y1 - touch.y2) > 30) { swipeTimeout = setTimeout(function () { var type = 'swipe' + swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2); if (touch.name == 'swipe' || touch.name == type) { touch.cb(e); } touchList.forEach(function (touch) { if (touch.name == 'swipe' || touch.name == type) { touch.cb(e); } }); touch = {}; touchList = []; }, 0); } // don't fire tap when delta position changed by more than 30 pixels, // for instance when moving to a point and back to origin else if (deltaX < 30 && deltaY < 30) { tapTimeout = setTimeout(function () { var isLongTap = Date.now() - lastTime > longTapDelay; if (isLongTap) { if (touch.name == 'longtap') { touch.cb(e); } touchList.forEach(function (touch) { if (touch.name == 'longtap') { touch.cb(e); } }); } // trigger double tap immediately else if (touch.isDoubleTap && touch.vd == lastTouch.vd) { if (touch.name == 'doubletap') { touch.cb(e); } touchList.forEach(function (touch) { if (touch.name == 'doubletap') { touch.cb(e); } }); } touch = {}; touchList = []; }, 0); } else { touch = {}; touchList = []; } deltaX = deltaY = 0; } ;});