input要素とbutton要素のイベント発火について


2024年 01月 25日

開発したフォームの2重送信が発生していたり、Enterを押しても送信されないということがありました。onClickに設定していたJSが意図せず発火していた、button要素にtypeを指定していなかった等々。そこで、本記事では意図せぬイベントの発火・未発火などを防ぐためにフォームにおける<input><button>についてまとめます。

その1

以下のようなフォームを例に挙げます。

このフォームは以下のようなHTMLで構成されているとします。

<form>
  <p>名前</p>
  <input />
  <p>メールアドレス</p>
  <p>お問い合わせ</p>
  <input />
  <button>戻る</button>
  <button>送信</button>
</form>

ここで名前、メールアドレス、お問い合わせを入力して Enterキー を押すと何が起きるでしょうか?

正解は

「戻るボタンのみのclickイベントが発火し、フォームのsubmitイベントが発火する」

です。

解説

  1. buttonタグはデフォルトでsubmitが適用される
    • buttonタグにはtype属性を追加することができます。type属性には、submit、reset、button の値を指定できますが、何も指定しない場合はsubmitが指定された場合と同じ挙動をします。なので、今回の場合は戻るボタンも送信ボタンもsubmitボタンになっています。
  2. submitボタンが複数ある場合にEnterを押すと1つ目のsubmitボタンがクリックされた判定になる
    • HTML Standard 4.10.21.2 Implicit submissionに仕様が記載されている通り、フォーム要素のデフォルトボタンは、ツリー順序で最初のsubmitボタンとなっています。
    • 今回の場合は戻るボタンがツリー順序で最初に定義されているsubmitボタンのため、戻るボタンがクリックされた判定になりました。

Enterを押した時に戻るボタンではなく送信ボタンが押されるようにするには以下のようにするべきでした。

<form>
  <p>名前</p>
  <input />
  <p>メールアドレス</p>
  <input />
  <p>お問い合わせ</p>
  <input />
  <button type="button">戻る</button>
  <button>送信</button>
</form>

その2

では、以下のような構成にした場合にお問い合わせを入力した後Enterを押すと何が起きるでしょうか?

<form>
  <p>お問い合わせ</p>
  <input />
  <button type="button">送信</button>
</form>

submitボタンがないし、Enterを押しても何も起こらない?送信ボタンがclickされた判定にはなるけどsubmitはされない?

正解は

「送信ボタンのclickイベントは発火せず、フォームのsubmitイベントが発火する」

です。

解説

  1. type=button のボタンはEnterではclickイベントは発火しない
    • ボタンが1つであろうと2つであろうと、type=buttonが指定されたボタンがEnterキーでclickイベントが発火することはありません。
  2. input要素が1つのみの場合、ボタンに関わらずEnterキーでsubmitイベントが発火する
    • input要素が1つのみの場合にEnterキーで送信したくない場合はformタグにonsubmit=return false;を指定して、buttonタグのonClickでsubmitする等の工夫が必要になります。

まとめ

  • buttonタグはデフォルトでsubmitが適用される
  • submitボタンが複数ある場合にEnterを押すと1つ目のsubmitボタンがクリックされた判定になる
  • type=buttonのボタンはEnterではclickイベントは発火しない
  • input要素が1つのみの場合、ボタンに関わらずEnterキーでsubmitイベントが発火する