JavaScript で長押し時に実行するイベントを定義する機能というのはいわゆる言語標準としては実装されていない。 つまりクリックイベントであれば HTMLElement.onclick に設定すれば良い (若しくは HTMLElement.addEventListener('click', function)) が HTMLElement.onlongpressHTMLElement.addEventListener('longpress', function) 的なものは用意されていないということだ。 そのために長押し時に何かするライブラリが Vue.js や jQuery 向けに公開されているが、ピュア JavaScript 向けには見た感じ存在しない。 そしてそういったコードは検索するといくつか出てくるが、どれも何だか複雑なので今回わかりやすい形で自分で実装してみた。

定義

本当は HTMLElement.addEventListener('longpress', function) みたいな感じでコールできるようにしたかったが、それは addEventListener メソッドをオーバーライドしないといけなそうな感じに見えたので止めて HTMLElement.setOnLongPressListener() とコールバックを設定して実行させる形にした:

HTMLElement.prototype.setOnLongPressListener = function(listener, interval = 800) {
    let isInProgress = false;  // 長押し中かどうか
    this.addEventListener('mousedown', () => {
        isInProgress = true;
        setTimeout(() => {
            if (isInProgress) {
                listener();
            }
        }, interval);
    });
    this.addEventListener('mouseup', () => {
        isInProgress = false;
    });
};

ギミックは至って単純で mousedown した時にタイマーを起動して interval 経過後に mouseup されていなかったらコールバックを実行するというものだ。 コードを読めばすぐ分かると思う。 長押しを検出するミリ秒はデフォルト 0.8 秒とした。

使用例

document.querySelectorAll('table tbody td').forEach(element => {
    element.setOnLongPressListener(() => element.style.borderColor = 'blue');
});
document.querySelectorAll('table tbody td').forEach(element => {
    element.setOnLongPressListener(() => element.style.backgroundColor = 'red', 1500);
});

このコードを実行するとすべてのテーブルの tbody 内のセルを長押しすると 0.8 秒後に枠線が青くなり 1.5 秒後に背景が赤くなる。