「ロゴを5回連打すると隠しモードが出る」「同意ボタンを2回押さないと進めない」など、クリック回数をキーに処理を出し分けたい場面は意外とあります。ポイントは、回数を累積で数えるのか、一定時間内の連打として数えるのかを決めることです。この記事では基本のカウントから、連打検知・ダブル/トリプルクリック・再利用クラスまでを整理します。
- クリック回数をカウントして閾値で処理を実行する基本
- 処理を一度だけ実行する(フラグ管理)
- 一定時間内にN回クリック(連打)を検知する
event.detailによるダブル・トリプルクリック判定- 隠し機能・隠しリンクの実用例
- 閾値・時間窓を指定できる再利用クラス
ClickTrigger
++ し、閾値に達したら処理を実行します。「累積」ならそのまま数え、「一定時間内の連打」ならsetTimeout で一定時間操作がなければカウンタを 0 に戻します。ダブル/トリプルなど連続クリックだけなら event.detail が手軽です。基本:クリック回数をカウントして閾値で実行する
まずはボタンのクリック回数を変数に記録し、閾値に達したら処理を実行する基本形です。
<button id="secret-btn" type="button">クリックしてみて</button> <p id="message"></p>
const button = document.getElementById("secret-btn");
const message = document.getElementById("message");
let clickCount = 0;
const threshold = 5; // 5回で発火
button.addEventListener("click", () => {
clickCount++;
if (clickCount >= threshold) {
message.textContent = "隠し機能が起動しました!";
clickCount = 0; // また数え直す場合はリセット(不要なら削除)
}
});
発火後に
clickCount = 0 とすれば何度でも繰り返せます。リセットしなければ閾値到達後は毎回発火し続けます。クリックイベントの基礎はクリックイベントの設定方法(addEventListener・イベント委任)を参照してください。処理を一度だけ実行する
「一度起動したら以降は反応させない」なら、処理済みフラグで管理します。{ once: true } オプションは「最初の1クリックで解除」なので回数カウントには使えない点に注意します。
let clickCount = 0;
let hasTriggered = false;
button.addEventListener("click", () => {
if (hasTriggered) return; // 起動済みなら何もしない
clickCount++;
if (clickCount >= threshold) {
message.textContent = "一度だけの隠し処理が実行されました。";
hasTriggered = true;
}
});
一定時間内にN回クリック(連打)を検知する
隠しコマンドのように「素早く5回」を検知したいときは、クリックのたびにタイマーを貼り直し、一定時間クリックが途切れたらカウントを 0 に戻します。こうすると「ゆっくり5回」では発火せず、連打したときだけ発火します。
let clickCount = 0;
let resetTimer = null;
const threshold = 5;
const within = 2000; // 2秒以内
button.addEventListener("click", () => {
clickCount++;
// クリックのたびにリセット用タイマーを貼り直す
clearTimeout(resetTimer);
resetTimer = setTimeout(() => { clickCount = 0; }, within);
if (clickCount >= threshold) {
message.textContent = "連打を検知しました!";
clickCount = 0;
clearTimeout(resetTimer);
}
});
時間制限なしの累積カウントは「合計◯回」、時間内カウントは「素早く◯回(連打)」に向きます。時間窓を短くしすぎると普通の操作では到達できず、長すぎると連打の意味が薄れます。
setTimeout の詳しい使い方はsetTimeout の使い方(遅延実行・clearTimeout)をご覧ください。ダブル・トリプルクリックを判定する(event.detail)
「連続して2回・3回」だけを判定したいなら、click イベントの event.detail が手軽です。連続クリック回数が入り、ダブルクリックなら 2、トリプルクリックなら 3 になります。
button.addEventListener("click", (e) => {
// e.detail = 連続クリック回数(2=ダブル, 3=トリプル)
if (e.detail === 3) {
message.textContent = "トリプルクリックを検出しました";
}
});
event.detail の注意点event.detail はブラウザのマルチクリック判定の間隔内で連続したときだけ増えます。クリックが遅い・ポインタが大きく動くとカウントはリセットされ、間隔やしきい値はブラウザ任せです。「自分で決めた時間内にN回」を厳密に判定したいなら、前章のタイマー方式を使ってください。実用例:クリック回数で隠しリンクを表示する
閾値に達したときだけ隠しリンクを表示する例です。判定は必ずクリックハンドラの中で行います(最初は hidden で隠しておきます)。
<button id="reveal-btn" type="button">???</button> <a href="/secret/" id="secret-link" hidden>秘密のページへ</a>
const revealBtn = document.getElementById("reveal-btn");
const secretLink = document.getElementById("secret-link");
let clickCount = 0;
const threshold = 5;
revealBtn.addEventListener("click", () => {
clickCount++;
if (clickCount >= threshold) {
secretLink.hidden = false; // 隠しリンクを表示
}
});
完成形:再利用できる ClickTrigger クラス
「累積/時間内」「一度だけ/繰り返し」を切り替えられる再利用クラスにまとめました。要素・回数・時間窓・コールバックを渡すだけで使えます。
class ClickTrigger {
constructor(target, options = {}) {
this.el = typeof target === "string"
? document.querySelector(target)
: target;
this.count = options.count ?? 5; // 発火に必要な回数
this.within = options.within ?? 0; // 0 なら累積、>0 なら時間内(ms)
this.once = options.once ?? false; // 一度だけ発火するか
this.onTrigger = options.onTrigger; // 発火時のコールバック
this.clicks = 0;
this.timer = null;
this.done = false;
this._handle = this._handle.bind(this);
if (this.el) this.el.addEventListener("click", this._handle);
}
_handle(e) {
if (this.done) return;
this.clicks++;
// 時間内モードなら、一定時間途切れたらカウントを戻す
if (this.within > 0) {
clearTimeout(this.timer);
this.timer = setTimeout(() => { this.clicks = 0; }, this.within);
}
if (this.clicks >= this.count) {
this.clicks = 0;
clearTimeout(this.timer);
if (this.once) {
this.done = true;
this.el.removeEventListener("click", this._handle);
}
this.onTrigger?.(e); // 発火
}
}
}
// 使い方:ロゴを2秒以内に5回クリックで隠しモード(一度だけ)
new ClickTrigger("#logo", {
count: 5,
within: 2000,
once: true,
onTrigger: () => console.log("隠しモード起動!"),
});
「連打防止」とは目的が逆
この記事は「N回クリックされたら発火させる」処理です。逆に、二重送信や誤操作を防ぐために短時間の連続クリックを無効化したい場合は、ボタンを連打防止!一定時間内の複数クリックを無効化する方法や、送信ボタン特有の送信ボタンの二重クリックを防止する方法が向いています。目的に合わせて使い分けてください。
なお、スマートフォンでもタップは click イベントとして発火するため、基本的に同じコードで動きます。タッチ環境で反応しない場合はスマホでクリックイベントが動作しない場合の原因と解決方法を確認してください。
よくある質問(FAQ)
click イベントで ++ して閾値に達したら処理を実行します。発火後に 0 に戻せば繰り返し使え、フラグで管理すれば一度だけにできます。setTimeout でリセット用タイマーを貼り直し、一定時間クリックが途切れたらカウントを 0 に戻します。これで連打のときだけ発火します。click イベントの event.detail が連続クリック回数を表し、トリプルクリックなら 3 になります(if (e.detail === 3))。ただし間隔やリセットはブラウザ任せなので、厳密な時間制御が必要ならタイマー方式を使ってください。まとめ
- 累積カウント:クリックごとに
++し閾値で実行(リセットで繰り返し可) - 一度だけ:処理済みフラグで以降を無効化
- 一定時間内にN回:
setTimeoutでカウントをリセットして連打を検知 - ダブル/トリプル:
event.detailが手軽(厳密な時間制御はタイマー方式) - 連打防止は目的が逆:無効化したいなら専用の手法を使う
用途に合わせて「累積か時間内か」「一度きりか繰り返しか」を選び、ClickTrigger クラスをベースに調整してみてください。

