
もはや入力フォームは、自分の人生のアルゴリズムと自分で認識していますが、この度仕事で行き詰まったポイントが合ったので、それと合わせて、入力フォームのsubmitコントロール方法を備忘録しておきたいと思います。
ケース1. Submitでよくある次イベントの制御方法
入力フォームを送信するWebページで、送信時にバリデーション処理を行う場合に、
複数の処理タイミングが違う処理が別々のモジュールで処理する事があります。
モジュールが、API、ライブラリ、プラグイン、CDN、別の人が作ったclass・・・などなど
要するに、onsubmitをハックする機能は、Javascriptで容易に設置できるんだけれど、2つ以上のイベント設置をしてしまうと途端に"脳みそこんがりコーン"になってしまうのである。
どんなケース?
とある、入力値を元に、レスポンスを返すシステムがあった場合、
const submit_button = document.querySelector(`button[type="submit"][name="submit"]`)
submit.button.addEventListener("submit", e => {
e.preventDefault()
// 入力フォームの値バリデーションチェック
})
submit.button.addEventListener("submit", e => {
e.preventDefault()
// 値の文字列置換処理をしてからデータ送信
new Post(this)
})
上記の場合、バリデーションチェックを行った場合、"e.preventDefault()"をセットしているから、submit処理は回避されるが、
最初のバリデーションチェックで、エラーが出ていても、次の文字列置換処理を行ってポスト(サーバーにデータを送信処理)までが実行されてしまう。
このケースの対処法
addEventListenerを設置した順番で、1番目(バリデーションチェック)処理の箇所で、エラーがあれば次のコードをセットするだけでいい。
e.stopImmediatePropagation()
こうすることで、2番目のイベント発火を停止させることができる。
この命令は、「呼び出されている同じイベントの他のリスナーを抑止する」機能なのだそうだ。
参考 :
Event: stopImmediatePropagation() メソッド
ケース2. 外部ライブラリが勝手に submit をフックしてくる問題
自前で form.addEventListener("submit", ...) を書いているのに、外部ライブラリ(バリデーション系、UI系、WordPress系プラグインなど)が裏で勝手に submit をハンドリングしてしまうことがある。
こういう時は「自分の処理が最優先で動く保証」が必要になる。
その手段の1つが capture モード
form.addEventListener("submit", e => {
e.preventDefault()
// 自分の最優先チェック
if (!checkUserInput()) {
e.stopImmediatePropagation()
return
}
}, { capture: true })
capture を true にすると「冒頭で発火」するので、後から差し込まれる謎の submit ハンドラよりも前に判定できる。
結果として「ライブラリ側が勝手に送信する」事故を防ぎやすくなる。
ケース3. submit ボタンの種類が複数あって制御が地獄化するパターン
例えばフォーム内に 確認、下書き保存、本登録 のような複数 submit ボタンがあるケース。
これらは実は、すべて同じ submit イベントで発火する。
どのボタンで押されたかを判定したい場合は、submit イベント内で以下のようにすると良い。
form.addEventListener("submit", e => {
e.preventDefault()
const clicked = e.submitter // ← 押されたボタンを特定!
if (clicked.name === "draft") {
saveDraft()
e.stopImmediatePropagation()
return
}
if (!validate()) {
showError()
e.stopImmediatePropagation()
return
}
send正式送信()
})
e.submitter は知られていないが、複数ボタンフォームでは救世主的存在。
これにより「ボタンごとに処理を変えるために submit を乱立させる」必要がなくなり、イベント衝突リスクも激減する。
あとがき
submit の制御ポイントは、以下の3つを押さえるだけで劇的に安定する。
1. preventDefault() … 送信を止める
2. stopImmediatePropagation() … 他の submit イベント発火を止める
3. e.submitter / capture: true … イベント衝突を避けるための最後の砦
フォーム送信は地味に複雑だが、イベントの「伝播」と「優先順位」を理解すると、一気にアルゴリズムとして整理される。
これが理解できると、あなたも、submitマスターになれる(かも)。
え?なりたくない?
0 件のコメント:
コメントを投稿