docs: function onTouch(element, eventType, handler) {
      var self = this;
  
      this.bindDom(element, Hammer.EVENT_TYPES[eventType], function bindDomOnTouch(ev) {
        var sourceEventType = 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(sourceEventType.match(/mouse/) && touch_triggered) {
          return;
        }
  
        // mousebutton must be down or a touch event
        else if(sourceEventType.match(/touch/) ||   // touch events are always on screen
          sourceEventType.match(/pointerdown/) || // pointerevents touch
          (sourceEventType.match(/mouse/) && ev.which === 1)   // mouse is pressed
          ) {
          enable_detect = true;
        }
  
        // mouse isn't pressed
        else if(sourceEventType.match(/mouse/) && !ev.which) {
          enable_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(sourceEventType.match(/touch|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(enable_detect) {
          // update pointerevent
          if(Hammer.HAS_POINTEREVENTS && eventType != Hammer.EVENT_END) {
            count_touches = Hammer.PointerEvent.updatePointer(eventType, ev);
          }
          // touch
          else if(sourceEventType.match(/touch/)) {
            count_touches = ev.touches.length;
          }
          // mouse
          else if(!touch_triggered) {
            count_touches = sourceEventType.match(/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 == Hammer.EVENT_END) {
            eventType = Hammer.EVENT_MOVE;
          }
          // no touches, force the end event
          else if(!count_touches) {
            eventType = Hammer.EVENT_END;
          }
  
          // store the last move event
          if(count_touches || last_move_event === null) {
            last_move_event = ev;
          }
  
          // trigger the handler
          handler.call(Hammer.detection, self.collectEventData(element, eventType, self.getTouchList(last_move_event, eventType), ev));
  
          // remove pointerevent from list
          if(Hammer.HAS_POINTEREVENTS && eventType == Hammer.EVENT_END) {
            count_touches = Hammer.PointerEvent.updatePointer(eventType, ev);
          }
        }
  
        // on the end we reset everything
        if(!count_touches) {
          last_move_event = null;
          enable_detect = false;
          touch_triggered = false;
          Hammer.PointerEvent.reset();
        }
      });
    }