解説
一度だけ反応するボタンを作る:addEventListenerのonceとリセットを試そう
once:trueは最初のイベントでリスナーを外す指定。通常のクリック回数と比較し、登録し直しや二重送信防止との違いを確認する。

案内を最初のクリックだけ表示したい。JavaScriptのaddEventListenerには、イベントを一度受け取ったらリスナーを取り除くonceという設定があるよ。
リスナーは、クリックなどのイベントを受け取って処理するために登録する関数。今回は普通のボタンと、一回だけ数えるボタンを比べる。ブラウザだけで動き、通信や保存はしないよ。
once:trueを付けて登録する
button.addEventListener("click", handleClick, { once: true });
最初にクリックのイベントを受け取るとhandleClickが実行され、そのリスナーは取り除かれる。同じボタンをもう一度クリックしても、この登録分の処理は実行されない。
ボタンをdisabledにする指定とは違うよ。見た目も自動的には変わらず、他のリスナーまでまとめて停止するものではない。
作例では二つの回数を比べる
普通のボタンには通常のリスナー、一回だけのボタンにはonce付きのリスナーを登録している。
- 普通のボタンを3回押す。回数は3になる。
- 一回だけのボタンを3回押す。回数は1のままになる。
- 「最初から試す」で両方を0へ戻す。
- 一回だけのボタンを押し、もう一度1になることを確かめる。
リセットは表示の数字だけを戻すのではなく、外れたリスナーを登録し直す操作も行っている。数字だけ0にしても、登録が外れたままなら次のクリックを数えられないんだ。
同じ関数を使って登録と解除を対応させる
button.removeEventListener("click", handleClick);
button.addEventListener("click", handleClick, { once: true });
作例では名前のある関数を使い、リセット時に登録を整えてから追加する。毎回別の関数を作って追加すると、別々のリスナーが残る原因になることがあるよ。
captureなどの条件を変える場合は、解除の条件も合わせる必要がある。今回は通常のバブリング段階のclickに絞った例だね。
一回だけのリスナーと、二重送信の防止は別
onceは、その登録が一度実行された後に外れる機能。別のリスナー、別の画面、再読み込みなどからの処理まで、一度しか実行されないと保証するものではない。
実際の申込みや支払いでは、サーバー側で重複処理を防ぐ設計なども必要になる。今回のクリック回数だけの作例を、二重決済を防ぐ完成した仕組みとして使わないようにしよう。
編集部ではChromiumで3回ずつのクリック、リセット後の再登録、回数の変化を確認した。実際のフォームの送信や、サーバーの重複防止は実行していないよ。
イベントを受け取る場所はtargetとcurrentTarget、フォームのボタンの種類はbuttonのtypeも合わせて見てみよう。
動かしてみよう:最初の一回だけの処理
二つのボタンを何度か押し、回数とリセット後の再登録を確認しよう。

みんなのコメント 0
感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。
最初のコメントをどうぞ。