フォームの送信ボタンやAjax処理などで、ユーザーが同じボタンを何度もクリックしてしまうと、重複送信や想定外の動作が起きることがあります。こうした「連打」を防ぐためには、JavaScriptでクリックを一時的に無効化する処理を加えることが有効です。
基本の連打防止方法:クリック後にボタンを無効化する
最もシンプルな方法は、ボタンがクリックされた直後にdisabled属性を付けるやり方です。
<button id="submitBtn">送信</button>
<script>
document.getElementById('submitBtn').addEventListener('click', function () {
this.disabled = true; // ボタンを無効化
// ここに送信処理などを書く
console.log('送信処理を実行');
});
</script>
この方法は、1度目のクリックでボタンが無効になり、連続してクリックされても処理が走らなくなります。
一定時間後に再び有効にする
一度だけではなく、数秒後に再びクリックを有効にしたい場合は、setTimeout()を使ってdisabledを解除します。
<button id="sendBtn">送信</button>
<script>
document.getElementById('sendBtn').addEventListener('click', function () {
const btn = this;
btn.disabled = true;
console.log('送信処理中...');
// 3秒後に再び有効にする
setTimeout(function () {
btn.disabled = false;
console.log('ボタンが再び有効になりました');
}, 3000);
});
</script>
フラグを使った連打防止の例
disabledを使わず、JavaScript内でフラグ(状態変数)を管理して連打を防ぐこともできます。
<button id="actionBtn">実行</button>
<script>
let isClicked = false;
document.getElementById('actionBtn').addEventListener('click', function () {
if (isClicked) {
console.log('連打防止中です');
return;
}
isClicked = true;
console.log('処理開始');
// 処理時間のシミュレーション
setTimeout(function () {
isClicked = false;
console.log('処理完了・再度クリック可能に');
}, 2000);
});
</script>
この方法ならボタンの見た目を変えずに処理制御できるため、デザインを維持したいケースに向いています。
フォーム送信時の対策にも有効
これらの連打防止処理は、フォームの送信ボタンにも簡単に応用できます。特にサーバー側で重複送信を防げない構成の場合は、フロントエンド側での対策が必須です。
よくある質問(FAQ)
Q. JavaScriptでボタンの連打を一定時間無効にするには?
A. clickイベントでbutton.disabled = trueにし、setTimeoutで指定時間後にfalseに戻します。これでthrottleと同様の効果が得られます。
Q. debounce(デバウンス)とthrottle(スロットル)の違いは?
A. debounceは最後の呼び出しからn秒後に1回実行します。throttleはn秒間で最大1回実行します。連打防止にはthrottle、検索入力の絞り込みにはdebounceが向いています。
Q. 複数のボタンそれぞれに連打防止を設定するには?
A. 各ボタンにclickイベントを設定し、それぞれthrottle/debounce関数でラップします。または共通の処理関数に対してclosureを使って状態を独立管理する方法もあります。
まとめ
ユーザー体験の向上と不具合防止のためにも、ボタンの連打対策は必ず実装しておきましょう。実際のプロジェクトでは、送信完了後に画面を遷移させる処理と組み合わせることも多いので、必要に応じて応用してください。

