Add Double Tap

by amindunited

HTML

<div id="parent">
  <div class="element">
    <h2>
      Element Title
    </h2>
    <p>
      Element BodyText
    </p>
  </div>
</div>

CSS

#parent {
  padding: 2rem;
  border: solid 05.rem grey;
  
}

.element {
  cursor: pointer;
  display: inline-block;
  border: solid 1px rgba(127, 127, 127, 0.5);
  border-radius: 0.4rem;
  padding: 0.5rem 1rem;
  text-align: center;
  width: 10rem;
  height: 8rem;
  transition: all 500ms ease-in-out;
}
.element > * {
  user-select: none;
}

.element.tapped {
  background-color: rgba(0, 127, 127, 0.5);
}

JavaScript

/** 
 * Double Tap
 * 
 * Example Use on Last ~10 lines below
 */

const parent = document.querySelector('#parent');
const element = document.querySelector('.element');
const tappedClassName = 'tapped';
const tapDuration = 400;

const customLogger = (...args) => {
	console.log(...args);
};


/**
 * @param element: HTMLElement - The target HTML Element 
 * @param options: {
 * 										tapDuration: 400,
 *									  customLogger: () => null,
 *										tappedClassName: string;
 *									}
 * Return function RemoveDoubleTap - A function to remove doubleTap listeners  
 */
const addDoubleTap = (element, options = {
	tapDuration: 400,
  tappedClassName: 'tapped',
  customLogger: () => null }) => {
  
	const { tapDuration, customLogger } = options;
  const logger = customLogger;
	let tapCount = 0;
	let timeout;

	// Cleans up tap Count and listeners
	const mouseupTimeoutFn = () => {
  	logger('[doubleTap]: Timeout.');
    element.removeEventListener('mouseup', mouseUpHandler);
    if (tapCount !== 2) {
      element.classList.remove(tappedClassName);
      tapCount = 0;
    }
  };

	// setup the timeout for mouseUp / tap completion
  const mouseupTimeout = () => {
    const timeout = setTimeout(mouseupTimeoutFn, tapDuration);
    return timeout;
  };

	// On mousedown setup timeout and mouseup listeners
  const mouseDownHandler = (e) => {
	  logger('[doubleTap]: MouseDown.');
    // Clear any existing 'timeout listeners'
    clearTimeout(timeout);
    element.addEventListener('mouseup', mouseUpHandler);
    timeout = mouseupTimeout();
  };

	// Mouseup increase count, emit doubletap event, cleanup
  const mouseUpHandler = (e) => {
    tapCount += 1;

		logger('[doubleTap]: MouseUp.');

    if (tapCount === 2) {
      element.classList.add(tappedClassName);
      
			logger('[doubleTap]: MouseUp. TapCount', tapCount, 'Emiting DoubleTap Event');
      const doubleTapEvent = new CustomEvent('doubletap', {...e});
      dispatchEvent(doubleTapEvent);
    }

    if...