All files / packages/tools/src/eventListeners/touch preventGhostClick.js

84.61% Statements 22/26
87.5% Branches 7/8
100% Functions 7/7
84.61% Lines 22/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73            1x 1x               126x   126x 1x               1x     126x           1x 1x     256x   256x 640x         534x   534x 1335x       1x 1x     267x 267x       128x 128x 128x              
// Functions to prevent ghost clicks following a touch
// Since the event lifecycle is touchstart, mousedown, touchend, mouseup
// we want to prevent mousedown and mouseup events after touch events
// All credit to @kosich
// https://gist.github.com/kosich/23188dd86633b6c2efb7
 
const antiGhostDelay = 2000,
  pointerType = {
    mouse: 0,
    touch: 1,
  };
 
let lastInteractionType, lastInteractionTime;
 
function handleTap(type, e) {
  const now = Date.now();
 
  if (type !== lastInteractionType) {
    Iif (now - lastInteractionTime <= antiGhostDelay) {
      e.preventDefault();
      e.stopPropagation();
      e.stopImmediatePropagation();
 
      return false;
    }
 
    lastInteractionType = type;
  }
 
  lastInteractionTime = now;
}
 
// Cacheing the function references
// Necessary because a new function reference is created after .bind() is called
// http://stackoverflow.com/questions/11565471/removing-event-listener-which-was-added-with-bind
const handleTapMouse = handleTap.bind(null, pointerType.mouse);
const handleTapTouch = handleTap.bind(null, pointerType.touch);
 
function attachEvents(element, eventList, interactionType) {
  const tapHandler = interactionType ? handleTapMouse : handleTapTouch;
 
  eventList.forEach(function (eventName) {
    element.addEventListener(eventName, tapHandler, { passive: false });
  });
}
 
function removeEvents(element, eventList, interactionType) {
  const tapHandler = interactionType ? handleTapMouse : handleTapTouch;
 
  eventList.forEach(function (eventName) {
    element.removeEventListener(eventName, tapHandler);
  });
}
 
const mouseEvents = ['mousedown', 'mouseup', 'mousemove'];
const touchEvents = ['touchstart', 'touchend'];
 
function disable(element) {
  removeEvents(element, mouseEvents, pointerType.mouse);
  removeEvents(element, touchEvents, pointerType.touch);
}
 
function enable(element) {
  disable(element);
  attachEvents(element, mouseEvents, pointerType.mouse);
  attachEvents(element, touchEvents, pointerType.touch);
}
 
export default {
  enable,
  disable,
};