JSFiddle - React, Tailwind, and code Playground

by mahny

HTML

<h2>押しっぱなし判定習作</h2>
<div>
  <button onMouseDown="test(event)" onTouchStart="test(event)">押しっぱなし!</button>
  <div id="result-console">(判定結果)</div>


  <button id="second-button" onClick="test2()">こっちは押しっぱなしならプログラムからクリックする</button>
  <div id="result-console2">(判定結果)</div>
</div>

JavaScript

function isHoldDown(targetElement, thresholdMsec = 1000) {
  return new Promise((resolve) => {

    const timerId = setTimeout(() => {
      resolve(true);
      removeListener();
    }, thresholdMsec);

    const touchendHandler = () => {
      resolve(false);
      removeListener();
    };

    const contextHandler = (event) => {
		  event.preventDefault();
    }

    const beforeTargetStyle = targetElement.style.userSelect;

    const removeListener = () => {
      clearTimeout(timerId);
      targetElement.removeEventListener('touchend', touchendHandler);
      targetElement.removeEventListener('mouseup', touchendHandler);
      targetElement.removeEventListener('contextmenu', contextHandler);
	    targetElement.style.userSelect = beforeTargetStyle;
    };

    targetElement.addEventListener('touchend', touchendHandler);
    targetElement.addEventListener('mouseup', touchendHandler);
    targetElement.removeEventListener('contextmenu', contextHandler);
    targetElement.style.userSelect = 'none';
  });
}

async function test(event) {
  const consoleEl = document.querySelector('#result-console');
  consoleEl.innerHTML = "(判定中)";

  const consoleEl2 = document.querySelector('#result-console2');
  consoleEl2.innerHTML = "-";

  // 押しっぱなし判定(とりあえず指定ミリ秒で押しっぱなし判定)
  const ret = await isHoldDown(event.target, 1000);
  consoleEl.innerHTML = `押しっぱなし判定: ${ret}`;
  
  // 2つ目のボタンをプログラムからクリックする
  if (ret) {
		document.querySelector('#second-button').click();
  }
}

function test2() {
  const consoleEl2 = document.querySelector('#result-console2');
  consoleEl2.innerHTML = "押下されました!";
}