JavaScriptでマウス(タップ)ボタンの長押しイベントを実装する方法

JavaScriptには長押しのイベントがない

JavaScriptでクリックイベントを実装する際はaddEventListenerでclickを指定すれば良いが、長押しに関してはlongpushのようなイベントはないため自分で各処理を作成する必要がある。

今回はボタンを長押し中にタイマーがカウントされ、長押しを解除すると「○秒長押しされました」と表示されるサンプルを作成する。

長押し中にボタンからカーソル(指)が離れた際は中断する処理も忘れずに。JavaScriptでマウス(タップ)ボタンの長押しイベントを実装する方法

「○秒長押しされました」と表示されるサンプル

長押しイベントの作成手順

最初にボタンのHTMLとCSSを記述。今回は赤いボタンにして長押し中は.activeを付けて明るい赤で表示されるようにした。

<div id="button"></div>
<p id="r">赤い部分をマウスかタップで長押し</p>
#button {
  width: 300px;
  height: 100px;
  margin: 0 auto 20px;
  background: #a00;
}
#button.active {
  background: #f00;
}
#r {
  text-align: center;
}

これで赤いボタンが表示されるのであとは長押し時のスクリプトを記述する。

レスポンシブウェブデザインでも使用できるようパソコンとスマートフォンのどちらのイベントでも対応できるよう出し分けしておくと良い。

※isSPと記述しているが今回のサンプルはタブレットを含む。

スマートフォンにはtouchstartやtouchendはあるがtouchleaveは存在しない。

そのためtouchmoveイベントの際にdocument.elementFromPointで現在のtouchmoveの要素を取得して、取得できていないときはmouseleaveと同じ状態であると考えられるため、下記のように記述すれば代用可能だ。

let count = 0;
let timer;
const ua = navigator.userAgent.toLowerCase();
const isSP = /iphone|ipod|ipad|android/.test(ua);
const b = document.getElementById('button');
const r = document.getElementById('r');
const eventStart = isSP ? 'touchstart' : 'mousedown';
const eventEnd   = isSP ? 'touchend' : 'mouseup';
const eventLeave = isSP ? 'touchmove' : 'mouseleave';

b.addEventListener(eventStart, e => {
  e.preventDefault();
  b.classList.add('active');
  timer = setInterval(() => {
    count++;
    r.textContent = (count / 100) + '秒';
  }, 10);
})

b.addEventListener(eventEnd, e => {
  e.preventDefault();
  if (count) {
    b.classList.remove('active');
    clearInterval(timer);
    r.textContent = (count / 100) + '秒長押しされました';
    count = 0;
  }
});

b.addEventListener(eventLeave, e => {
  e.preventDefault();
  let el;
  el = isSP ? document.elementFromPoint(e.touches[0].clientX, e.touches[0].clientY) : b;
  if (!isSP || el !== b) {
    b.classList.remove('active');
    clearInterval(timer);
    r.textContent = '処理を中断';
    count = 0;
  }
});

「○秒長押しされました」と表示されるサンプル