UNPKG

hammerjs

Version:

A javascript library for multi-touch gestures

258 lines (218 loc) 7.33 kB
/** * this holds the last move event, * used to fix empty touchend issue * see the onTouch event for an explanation * @type {Object} */ var last_move_event = null; /** * when the mouse is hold down, this is true * @type {Boolean} */ var should_detect = false; /** * when touch events have been fired, this is true * @type {Boolean} */ var touch_triggered = false; var Event = Hammer.event = { /** * simple addEventListener * @param {HTMLElement} element * @param {String} type * @param {Function} handler */ bindDom: function(element, type, handler) { var types = type.split(' '); Utils.each(types, function(type){ element.addEventListener(type, handler, false); }); }, /** * simple removeEventListener * @param {HTMLElement} element * @param {String} type * @param {Function} handler */ unbindDom: function(element, type, handler) { var types = type.split(' '); Utils.each(types, function(type){ element.removeEventListener(type, handler, false); }); }, /** * touch events with mouse fallback * @param {HTMLElement} element * @param {String} eventType like EVENT_MOVE * @param {Function} handler */ onTouch: function onTouch(element, eventType, handler) { var self = this; var bindDomOnTouch = function bindDomOnTouch(ev) { var srcEventType = ev.type.toLowerCase(); // onmouseup, but when touchend has been fired we do nothing. // this is for touchdevices which also fire a mouseup on touchend if(Utils.inStr(srcEventType, 'mouse') && touch_triggered) { return; } // mousebutton must be down or a touch event else if(Utils.inStr(srcEventType, 'touch') || // touch events are always on screen Utils.inStr(srcEventType, 'pointerdown') || // pointerevents touch (Utils.inStr(srcEventType, 'mouse') && ev.which === 1) // mouse is pressed ) { should_detect = true; } // mouse isn't pressed else if(Utils.inStr(srcEventType, 'mouse') && !ev.which) { should_detect = false; } // we are in a touch event, set the touch triggered bool to true, // this for the conflicts that may occur on ios and android if(Utils.inStr(srcEventType, 'touch') || Utils.inStr(srcEventType, 'pointer')) { touch_triggered = true; } // count the total touches on the screen var count_touches = 0; // when touch has been triggered in this detection session // and we are now handling a mouse event, we stop that to prevent conflicts if(should_detect) { // update pointerevent if(Hammer.HAS_POINTEREVENTS && eventType != EVENT_END) { count_touches = PointerEvent.updatePointer(eventType, ev); } // touch else if(Utils.inStr(srcEventType, 'touch')) { count_touches = ev.touches.length; } // mouse else if(!touch_triggered) { count_touches = Utils.inStr(srcEventType, 'up') ? 0 : 1; } // if we are in a end event, but when we remove one touch and // we still have enough, set eventType to move if(count_touches > 0 && eventType == EVENT_END) { eventType = EVENT_MOVE; } // no touches, force the end event else if(!count_touches) { eventType = EVENT_END; } // store the last move event if(count_touches || last_move_event === null) { last_move_event = ev; } // trigger the handler handler.call(Detection, self.collectEventData(element, eventType, self.getTouchList(last_move_event, eventType), ev) ); // remove pointerevent from list if(Hammer.HAS_POINTEREVENTS && eventType == EVENT_END) { count_touches = PointerEvent.updatePointer(eventType, ev); } } // on the end we reset everything if(!count_touches) { last_move_event = null; should_detect = false; touch_triggered = false; PointerEvent.reset(); } }; this.bindDom(element, Hammer.EVENT_TYPES[eventType], bindDomOnTouch); // return the bound function to be able to unbind it later return bindDomOnTouch; }, /** * we have different events for each device/browser * determine what we need and set them in the Hammer.EVENT_TYPES constant */ determineEventTypes: function determineEventTypes() { // determine the eventtype we want to set var types; // pointerEvents magic if(Hammer.HAS_POINTEREVENTS) { types = PointerEvent.getEvents(); } // on Android, iOS, blackberry, windows mobile we dont want any mouseevents else if(Hammer.NO_MOUSEEVENTS) { types = [ 'touchstart', 'touchmove', 'touchend touchcancel']; } // for non pointer events browsers and mixed browsers, // like chrome on windows8 touch laptop else { types = [ 'touchstart mousedown', 'touchmove mousemove', 'touchend touchcancel mouseup']; } Hammer.EVENT_TYPES[EVENT_START] = types[0]; Hammer.EVENT_TYPES[EVENT_MOVE] = types[1]; Hammer.EVENT_TYPES[EVENT_END] = types[2]; }, /** * create touchlist depending on the event * @param {Object} ev * @param {String} eventType used by the fakemultitouch plugin */ getTouchList: function getTouchList(ev/*, eventType*/) { // get the fake pointerEvent touchlist if(Hammer.HAS_POINTEREVENTS) { return PointerEvent.getTouchList(); } // get the touchlist if(ev.touches) { return ev.touches; } // make fake touchlist from mouse position ev.identifier = 1; return [ev]; }, /** * collect event data for Hammer js * @param {HTMLElement} element * @param {String} eventType like EVENT_MOVE * @param {Object} eventData */ collectEventData: function collectEventData(element, eventType, touches, ev) { // find out pointerType var pointerType = POINTER_TOUCH; if(Utils.inStr(ev.type, 'mouse') || PointerEvent.matchType(POINTER_MOUSE, ev)) { pointerType = POINTER_MOUSE; } return { center : Utils.getCenter(touches), timeStamp : Date.now(), target : ev.target, touches : touches, eventType : eventType, pointerType: pointerType, srcEvent : ev, /** * prevent the browser default actions * mostly used to disable scrolling of the browser */ preventDefault: function() { var srcEvent = this.srcEvent; srcEvent.preventManipulation && srcEvent.preventManipulation(); srcEvent.preventDefault && srcEvent.preventDefault(); }, /** * stop bubbling the event up to its parents */ stopPropagation: function() { this.srcEvent.stopPropagation(); }, /** * immediately stop gesture detection * might be useful after a swipe was detected * @return {*} */ stopDetect: function() { return Detection.stopDetect(); } }; } };