フォーム送信ボタンを二重クリックされると、同じ内容が複数回送信されてしまうことがあります。お問い合わせフォームや申込フォームでは、これが重複登録や二重決済の原因になるため、JavaScriptで送信ボタンを一時的に無効化しておく方法がよく使われます。
この記事では、フォーム送信時にボタンを二重クリックできないようにする基本的な方法を、初心者向けに分かりやすく解説します。シンプルな実装から、よくある注意点まで順番に見ていきましょう。
まずは基本の考え方を押さえる
二重クリックを防ぐには、送信が始まったタイミングでボタンを「押せない状態」にします。HTMLのdisabled属性を使うと、そのボタンはクリックできなくなります。
重要なのは、送信処理が始まったらすぐに無効化することです。これにより、ユーザーが連続でクリックしても、2回目以降の送信操作を受け付けにくくできます。
シンプルな実装例
まずは、フォーム送信時にボタンを無効化する基本コードです。
<form id="contactForm" action="/submit" method="post">
<label>
お名前
<input type="text" name="name" required>
</label>
<label>
メールアドレス
<input type="email" name="email" required>
</label>
<button type="submit" id="submitButton">送信する</button>
</form>
<script>
const form = document.getElementById('contactForm');
const submitButton = document.getElementById('submitButton');
form.addEventListener('submit', function () {
submitButton.disabled = true;
submitButton.textContent = '送信中...';
});
</script>
このコードでは、フォームが送信される瞬間にボタンを無効化しています。さらに、表示テキストを「送信中…」に変えることで、ユーザーに処理中であることが伝わりやすくなります。
ただし、このままでは送信後にページ遷移しないケースや、通信エラー時に再送信へ対応しづらいことがあります。実務では、状況に応じてもう少し丁寧に制御することが大切です。
送信後に再度押せるように戻す方法
Ajaxを使って非同期送信する場合や、バリデーションエラーで同じページに戻る場合は、必要に応じてボタンを再び有効化します。以下は、送信処理の完了後にボタンを戻す例です。
<form id="contactForm">
<input type="text" name="name" placeholder="お名前" required>
<button type="submit" id="submitButton">送信する</button>
</form>
<script>
const form = document.getElementById('contactForm');
const submitButton = document.getElementById('submitButton');
form.addEventListener('submit', async function (event) {
event.preventDefault();
if (submitButton.disabled) return;
submitButton.disabled = true;
submitButton.textContent = '送信中...';
try {
// ここで実際の送信処理を行う
await new Promise(resolve => setTimeout(resolve, 2000));
alert('送信が完了しました');
} catch (error) {
alert('送信に失敗しました');
} finally {
submitButton.disabled = false;
submitButton.textContent = '送信する';
}
});
</script>
この例では、finallyで必ずボタンを元に戻しています。送信成功時だけでなく、失敗時にも再度操作できるようにしている点がポイントです。
連打対策だけでなく二重送信も意識する
JavaScriptでボタンを無効化しても、それだけで完全に二重送信を防げるわけではありません。たとえば、通信が遅い環境では、送信ボタンを押した直後に別の方法で同じリクエストを送られる可能性があります。
そのため、本当に重要なフォームでは、サーバー側でも重複送信対策をしておくことが推奨されます。たとえば以下のような方法があります。
- ワンタイムトークンを使う
- 同じ送信内容の重複をサーバー側で検知する
- 処理完了前に同一ユーザーの再送信を拒否する
JavaScriptはあくまで「ユーザーの誤操作を減らすための補助」と考えると、安全に設計しやすくなります。
押せなくするだけでなく見た目も変える
ボタンを無効化すると見た目も変わるため、ユーザーが状態を理解しやすくなります。必要ならCSSで無効化時の見た目を整えましょう。
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
このようにしておくと、クリックできない状態が視覚的にも伝わりやすくなります。送信中であることが分かれば、ユーザーが何度も押してしまう可能性も下がります。
よくある実装ミス
二重クリック対策では、次のようなミスに注意してください。
- 送信完了後にボタンを戻さず、再送信できなくなる
- クリックイベントだけを止めて、Enterキーでの送信を考慮していない
- JavaScriptが無効な環境を想定していない
- 送信処理より前にボタンを無効化し、エラー時の復帰処理がない
特にフォーム送信は、ボタンのクリックだけでなく、キーボード操作でも行われます。submitイベントで制御しておくと、より確実に対応しやすくなります。
まとめ
フォーム送信ボタンの二重クリックを防ぐには、送信開始時にdisabled属性でボタンを無効化する方法が基本です。さらに、送信中の表示に切り替えたり、処理完了後に元に戻したりすると、ユーザーにとって分かりやすいUIになります。
ただし、JavaScriptだけでは完全な重複送信対策にはなりません。重要なフォームでは、サーバー側の対策もあわせて実装することで、より安全で実用的な仕組みになります。

