🧐

js学習メモ|イベントオブジェクトに対する疑問

2025/02/27に公開5

※注意※
このメモは私がJavaScript学習中に生じた疑問について書いています。
そのため、かなり初歩的なものや「何を言っているんだ」というのもあると思います。
自分の思考整理、理解するために執筆しているので、温かい目で見ていただけますと幸いです。
また、記述に誤りがありましたら、コメントにてご教示お願いいたします。

事の始まり

今回、Udemyのある講座でTODOリストの作成を行いました。
受講が終わり、復習として1から自分で書いてみようとやっていたところ
フォームのデフォルトの動作(ページのリロード)を防ぐために記述した「preventDefault」のところで疑問が発生。

今回の疑問は2つ

  • なぜ preventDefault() を使うには「イベントオブジェクト」が必要なのか?
  • 「e」や「event」など、変数名は任意だと言われているが、それでもなぜそのオブジェクトが必要なのか?

そもそも、なぜ疑問に感じたのか。

  • イベントオブジェクトは「任意の名前で受け取ることができる」と教えられているが、実際には preventDefault() のようなメソッドを使うために何か特別なオブジェクトが必要という部分が不明確だった
  • 変数名は任意だと聞いても、オブジェクトが必要である理由がわからなかった。(任意という言葉に混乱した)

解決、考え方

1. イベントオブジェクトは自動で渡されるオブジェクト

  • イベントオブジェクトは、イベントが発生したときにブラウザが自動で生成するオブジェクト
  • このオブジェクトには、イベントに関する詳細情報(例えば、クリックした座標や、キーボードのキーなど)が格納されている。
  • preventDefault() などのイベント関連のメソッドは、このイベントオブジェクトに紐づいているため、そのオブジェクトが必要になる。

2. イベントオブジェクトのメソッド(例:preventDefault())

イベントオブジェクトにはいくつかのメソッドが含まれている。
例えば

  • preventDefault() は、イベントのデフォルト動作を無効化するためのメソッド(例えば、リンクをクリックしてもページが遷移しないようにするなど)。

  • stopPropagation() は、イベントが親要素や他のリスナーに伝播するのを防ぐためのメソッド。

    ▶これらのメソッドは、イベントオブジェクトを通してアクセスする。

3. 変数名(e や event)が任意でも、オブジェクトが必要な理由

  • 変数名は任意だが、メソッドを使うためにはそのイベントオブジェクトが引数として渡されている必要がある。
  • つまり、変数名はあくまでイベントオブジェクトを指し示すための名前であり、そのオブジェクト自体が渡されなければ、メソッド(例えば preventDefault())を呼び出せない。
例(エラーになるケース)
addForm.addEventListener('submit', () => {
    preventDefault(); // ❌ 「何の preventDefault ?」となってエラー!
});
例(正しく動作するケース)
addForm.addEventListener('submit', event => {
    event.preventDefault(); // ✅ ちゃんとイベントオブジェクト (`event`) を通して実行
});

4. イベントオブジェクトがどのように渡されるのか

  • イベントリスナーがイベントを監視しているとき、イベントが発生すると、ブラウザがそのイベントオブジェクトを自動で渡してくれる。
  • そのイベントオブジェクトを使って、preventDefault() やその他のメソッドにアクセスできる。

まとめ

疑問点 解決策・考え方
preventDefault() を使うにはなぜイベントオブジェクトが必要なのか? イベントオブジェクトは、イベントが発生した際に自動で生成され、その情報を格納しているオブジェクト。メソッド(preventDefault())はこのオブジェクトに関連づけられているため、オブジェクトを使う必要がある。
e や event という変数名は任意なのに、なぜオブジェクトが必要なのか? 変数名は任意ですが、イベントオブジェクトそのものが渡されているので、そのオブジェクトを使ってメソッドを呼び出さなければならない。
イベントオブジェクトはどうやって渡されるのか? イベントが発生すると、自動的にイベントオブジェクトが渡され、そのオブジェクトを通してメソッド(例:preventDefault())が呼び出せる。

Discussion

junerjuner

イベント自体は mdn で構造見たらわかる様に 次の様に イベントオブジェクトに判定系が含まれているからでは?みたいなところあります。(その為、非同期を入れるとキャンセルができなくなったりします。

// #region イベントの利用
element.addEventListener('click', (e) => {
  if (e.cancelable) e.preventDefault();
});
// #endregion

// ...

// #region イベントの発行処理
const event = new Event("click", {cancelable: true});
element.dispatchEvent(event);
if (!event.defaultPrevented) {
 // イベント によるデフォルトの動作
}
// #endregion
eringieringi

コメントありがとうございます!
なるほど!「判定系があるから」というので少し理解が深まった気がします!

改めて整理させてください(間違いあったらすみません…)

①イベントオブジェクトにはイベントに関する情報が格納されている

例えば、クリックイベントではどこをクリックしたか(座標)や、どのボタンが押されたかなど、イベントが発生した詳細情報がイベントオブジェクトに格納される。
➡️クリックしたかどうかだけでなく、クリックした場所や回数などを確認することもできる。

②判定系のメソッドがある

クリックイベントのように、イベントオブジェクトには判定系のプロパティ(例:cancelable)があり、これに基づいてイベントを制御することができる。
➡️cancelable プロパティは、そのイベントがキャンセル可能かどうかを判定するために使う。
このプロパティによって、キャンセルできるかどうかをチェックした後で preventDefault() を使うという流れになる。

③だからイベントオブジェクトが必要

イベントが発生すると、ブラウザがそのイベントオブジェクトを生成して、私たちがそれを受け取って使う。
このオブジェクトには、クリックした場所や、キャンセル可能かどうかといった情報が含まれている。
➡️この情報があるからこそ、イベントを判定したり、デフォルト動作をキャンセルしたりできる。