複数の入力欄があるフォームで、入力途中に Enterキーを押したら意図せず送信されてしまった、という経験はよくあります。これは仕様どおりの動作(暗黙的な送信)ですが、JavaScriptで止めることができます。
ただし、単純に「フォーム全体でEnterを無効化」すると、textareaの改行や日本語入力の変換確定まで巻き込んで壊れます。この記事では、そうした落とし穴を避けた正しい無効化の方法を解説します。
keydown イベントで event.key === "Enter" を検知し preventDefault() します。その際 textareaとIME変換中のEnterは除外するのが必須。検索ボックスなどEnter送信が自然なフォームでは無効化しない(アクセシビリティに配慮)ようにします。なぜEnterでフォームが送信されるのか
HTMLのフォームには「暗黙的な送信(implicit submission)」という仕組みがあります。1行テキスト入力(<input type="text"> など)にフォーカスがある状態でEnterを押すと、フォームが自動的に送信されます。これは標準の動作です。
この送信はEnterキーのデフォルト動作なので、Enterが押された瞬間にそれを preventDefault() で打ち消せば止められます。
keydownでEnter送信を無効化する(textarea除外)
キー操作の検知には、廃止予定の keypress ではなく keydown を使います。そのうえで、textarea(改行が必要)と送信ボタン、IME変換中のEnterを除外します。
const form = document.getElementById("myForm");
form.addEventListener("keydown", (event) => {
if (
event.key === "Enter" &&
!event.isComposing && // IME変換確定のEnterは無視
event.target.matches("input:not([type=submit]):not([type=button])")
) {
event.preventDefault(); // 暗黙の送信を止める
}
});
ポイントは event.target.matches("input:not(...)") で1行テキスト入力に対象を絞っている点です。これにより textarea の改行や、送信ボタンを押した(Enterで押下した)ときの送信はそのまま動きます。event.key の詳しい扱いはキーボード入力を取得する方法を参照してください。
keypress を使う例が多いですが、keypress は廃止予定(deprecated)で一部キーで発火しないなど不安定です。キー操作の検知は keydown を使ってください。特定の入力欄だけ無効化する
フォーム全体ではなく、特定の1欄だけEnter送信を止めたい場合は、その要素に直接リスナーを付けます。
const keyword = document.getElementById("keyword");
keyword.addEventListener("keydown", (event) => {
if (event.key === "Enter" && !event.isComposing) {
event.preventDefault();
}
});
Enterで次の入力欄へ移動する(無効化の代替)
「送信はさせたくないが、Enterで次の欄に進めたい」というニーズも多いです。その場合は送信を止めたうえで、次のフォーム要素に focus() します。
form.addEventListener("keydown", (event) => {
if (event.key !== "Enter" || event.isComposing) return;
if (event.target.tagName === "TEXTAREA") return; // textareaは改行を優先
event.preventDefault();
const fields = [...form.querySelectorAll("input, select")];
const i = fields.indexOf(event.target);
if (i >= 0 && i < fields.length - 1) {
fields[i + 1].focus(); // 次の入力欄へ
}
});
注意:むやみに全フォームで無効化しない
フォーム入力をリアルタイムに扱う実装はフォーム入力をリアルタイムで監視する方法、Enter以外のキー制御はバックスペースキーを無効化する方法も参考になります。
よくある質問(FAQ)
keydown イベントで event.key === "Enter" かつ event.target.tagName !== "TEXTAREA" のときに event.preventDefault() を呼びます。textareaでは改行が必要なため除外し、廃止予定の keypress は使いません。keydown リスナーを付け、Enterキー時に preventDefault() します。フォーム全体ではなく個別に制御できるため、textareaなど他の要素に影響しません。preventDefault() で止めたうえで、次のフォーム要素に focus() します。querySelectorAll("input, select") で順序を取得し、現在のインデックス+1の要素へ移動します。event.isComposing が true になります。条件に !event.isComposing を加えて、変換確定のEnterを除外してください。これで入力中の誤作動を防げます。まとめ
Enterキーでのフォーム送信は、keydown イベントで検知して preventDefault() すれば無効化できます。その際 textareaの改行・IME変換確定のEnter・送信ボタンを巻き込まないよう、input:not([type=submit]) や isComposing で対象を絞るのが重要です。
廃止予定の keypress は使わず keydown を使い、Enter送信が自然なフォームでは無効化しない、というアクセシビリティへの配慮も忘れないようにしましょう。「送信は止めて次の欄へ進めたい」なら focus() での移動が便利です。
