define(['dom', 'events'], function (dom, events) { 'use strict'; function getTouches(e) { return e.changedTouches || e.targetTouches || e.touches; } function TouchHelper(elem, options) { options = options || {}; var touchTarget; var touchStartX; var touchStartY; var lastDeltaX; var lastDeltaY; var thresholdYMet; var self = this; var swipeXThreshold = options.swipeXThreshold || 50; var swipeYThreshold = options.swipeYThreshold || 50; var swipeXMaxY = 30; var excludeTagNames = options.ignoreTagNames || []; var touchStart = function (e) { var touch = getTouches(e)[0]; touchTarget = null; touchStartX = 0; touchStartY = 0; lastDeltaX = null; lastDeltaY = null; thresholdYMet = false; if (touch) { var currentTouchTarget = touch.target; if (dom.parentWithTag(currentTouchTarget, excludeTagNames)) { return; } touchTarget = currentTouchTarget; touchStartX = touch.clientX; touchStartY = touch.clientY; } }; var touchEnd = function (e) { var isTouchMove = e.type === 'touchmove'; if (touchTarget) { var touch = getTouches(e)[0]; var deltaX; var deltaY; var clientX; var clientY; if (touch) { clientX = touch.clientX || 0; clientY = touch.clientY || 0; deltaX = clientX - (touchStartX || 0); deltaY = clientY - (touchStartY || 0); } else { deltaX = 0; deltaY = 0; } var currentDeltaX = lastDeltaX == null ? deltaX : (deltaX - lastDeltaX); var currentDeltaY = lastDeltaY == null ? deltaY : (deltaY - lastDeltaY); lastDeltaX = deltaX; lastDeltaY = deltaY; if (deltaX > swipeXThreshold && Math.abs(deltaY) < swipeXMaxY) { events.trigger(self, 'swiperight', [touchTarget]); } else if (deltaX < (0 - swipeXThreshold) && Math.abs(deltaY) < swipeXMaxY) { events.trigger(self, 'swipeleft', [touchTarget]); } else if ((deltaY < (0 - swipeYThreshold) || thresholdYMet) && Math.abs(deltaX) < swipeXMaxY) { thresholdYMet = true; events.trigger(self, 'swipeup', [touchTarget, { deltaY: deltaY, deltaX: deltaX, clientX: clientX, clientY: clientY, currentDeltaX: currentDeltaX, currentDeltaY: currentDeltaY }]); } else if ((deltaY > swipeYThreshold || thresholdYMet) && Math.abs(deltaX) < swipeXMaxY) { thresholdYMet = true; events.trigger(self, 'swipedown', [touchTarget, { deltaY: deltaY, deltaX: deltaX, clientX: clientX, clientY: clientY, currentDeltaX: currentDeltaX, currentDeltaY: currentDeltaY }]); } if (isTouchMove && options.preventDefaultOnMove) { e.preventDefault(); } } if (!isTouchMove) { touchTarget = null; touchStartX = 0; touchStartY = 0; lastDeltaX = null; lastDeltaY = null; thresholdYMet = false; } }; this.touchStart = touchStart; this.touchEnd = touchEnd; dom.addEventListener(elem, 'touchstart', touchStart, { passive: true }); if (options.triggerOnMove) { dom.addEventListener(elem, 'touchmove', touchEnd, { passive: !options.preventDefaultOnMove }); } dom.addEventListener(elem, 'touchend', touchEnd, { passive: true }); dom.addEventListener(elem, 'touchcancel', touchEnd, { passive: true }); } TouchHelper.prototype.destroy = function () { var elem = this.elem; if (elem) { var touchStart = this.touchStart; var touchEnd = this.touchEnd; dom.removeEventListener(elem, 'touchstart', touchStart, { passive: true }); dom.removeEventListener(elem, 'touchmove', touchEnd, { passive: true }); dom.removeEventListener(elem, 'touchend', touchEnd, { passive: true }); dom.removeEventListener(elem, 'touchcancel', touchEnd, { passive: true }); } this.touchStart = null; this.touchEnd = null; this.elem = null; }; return TouchHelper; });