JavaScriptにおけるイベントハンドラーを解説

2023/02/11に公開

今回は、JavaScriptにおけるイベントハンドラーについて解説していきます。

細かい仕様などは理解してない人も多いと思うので、ぜひこちらの記事を参考にしてください。

イベントとは

まず、そもそもイベントとは何にかということを解説します。

イベントとは何かが起きたと言う信号になります。

例えば、要素がクリックされた、ホバーされたなどです。

JavaScriptではこれに合わせて、イベントハンドラーというコールバック関数を設定することができます。

つまり、「この要素がクリックされたらこの処理をしてください」とブラウザに伝えることができるのです。

イベントハンドラーの設定方法

次に、イベントハンドラーの設定方法を解説していきます。

まず、以下のようにHTMLに直接設定することが可能です。

<h1 onclick="console.log('hello')" id="title">Hello!!</h1>

イベントハンドラーは基本的に、on*という接頭辞で始まります。

そして、今回使用しているonclick以外にも数十種類あります。

また、JavaScriptで設定することも可能です。

const h1 = document.getElementById('title')
h1.onclick = () => {console.log("hello")}

ただ、この方法だと複数登録ができないです。

例えば、以下のように設定した場合は、後のhello2のログのみが出力されます。

const h1 = document.getElementById('title')
h1.onclick = () => {console.log("hello")}
h1.onclick = () => {console.log("hello2")}

このように、イベントハンドラーが1つしか設定できないというのは少し不便なので、以下の方法でイベントハンドラーを付与するのが一般的です。

const h1 = document.getElementById('title')
const hello = () => {
  console.log("hello")
}
h1.addEventListener('click',hello)

addEventListenerを使い、第一引数にイベント名、第二引数に関数を渡します。

ちなみに、onclickプロパティとaddEventListnerは別物なので、2つ登録した場合は登録順にそれぞれが実行されます。

また、removeEventListnerを使ってイベントハンドラーを削除することができます。

使い方は基本的にaddEventListenerと同じです。

const h1 = document.getElementById('title')
const hello = () => {
  console.log("hello")
}
h1.addEventListener('click',hello)
h1.removeEventListener('click',hello)

イベントハンドラーの仕様

次に、イベントハンドラの仕様についていくつか解説していきます。

イベントハンドラはブラウザにより実行されます。

そして、その際にイベントオブジェクトが引数として渡されます。

このイベントオブジェクトには、イベントがどこで起こったどのような種類のものかなどの情報が格納されています。

このイベントオブジェクトを使用したい場合は、単に引数を受け取ってやればOKです。

const h1 = document.getElementById('title')
const hello = (e) => {
  console.log("hello")
  console.log(e)
}
h1.addEventListener('click',hello)

また、イベントハンドラー内のthisはイベントが起こった要素の情報を参照します。

イベントの実行順(キャプチャリングとバブリング)

次にイベントの実行順について解説していきます。

ここの仕様は理解していない人も多いと思うので、参考になるかと思います。

まず、イベントは次の図のように3つのフェーズがあります。

引用元:https://ja.javascript.info/bubbling-and-capturing

まずイベントが発生した場合に、一番上のwindow要素からイベントの発生元となる、イベントターゲットを探しにいきます。

そして、イベントターゲットを見つけたら、そこから上に向かってイベントハンドラを実行していきます。

イベントターゲットを探しに行くフェーズをキャプチャリングフェーズ、イベントターゲットを見つけたフェーズをターゲットフェーズ、イベントターゲットから上に向かって順にイベントハンドラーを実行していくフェーズをバブリングフェーズと言います。

例えば、以下のようにイベントハンドラーを設定します。

<div id="face">
  <button id="event-target">
   event target
  </button>
</div>
const face = document.getElementById('face')
const hello = () => {
  console.log("hello at face")
}
face.addEventListener('click',hello)

const eventTarget = document.getElementById('event-target')
const hello2 = () => {
  console.log("hello at event-target")
}
eventTarget.addEventListener('click',hello2)

const hello3 = () => {
  console.log("hello at window")
}
window.addEventListener('click',hello3)

この場合は、以下の順でログが表示されるので、下から順にイベントハンドラーが実行されているということが分かるかと思います。

  1. hello at event-target
  2. hello at face
  3. hello at window

また、addEventListnerにオプションを設定することで、キャプチャリングフェーズでの実行も可能になります。

そして、stopPropagationをイベントハンドラーに設定することで、これらの動きを途中で止めることができます。

例えば、以下のように設定した場合は、hello at event-targetのみが出力されます。

const face = document.getElementById('face')
const hello = () => {
  console.log("hello at face")
}
face.addEventListener('click',hello)

const eventTarget = document.getElementById('event-target')
const hello2 = (e) => {
  console.log("hello at event-target")
  //
  e.stopPropagation()
}
eventTarget.addEventListener('click',hello2)

const hello3 = () => {
  console.log("hello at window")
}
window.addEventListener('click',hello3)

一応バブリングしないイベントもありますが、キャプチャリングは必ず起こります。

頭の片隅に置いておきましょう。

また、最後の最後にイベントのデフォルトの挙動が動きます。

例えば、aタグをクリックした場合は、バブリングフェーズの後にページ遷移というイベントのデフォルトの挙動が動きます。

そして、preventDefaultを使うことで、その挙動を止めることができます。

const a = document.getElementById('link')
const click = (e) => {
  e.preventDefault()
}
a.addEventListener('click',click)

最後の最後に実行されると言いましたが、途中でstopPropagationしても止まるわけではないのでそこは注意しましょう。

カスタムイベント

最後に、カスタムイベントについて解説していきます。

on*というイベントは数十種類あると言いましたが、独自に新たなイベントを作成することもできます。

まず、コードを見せた方が早いと思うので、次の通りです。

const customEvent = new CustomEvent('hoge');

const eventTarget = document.getElementById('event-target')
eventTarget.addEventListener('hoge', function() {
  console.log("custom event")
});

const hello = () => {
  console.log("hello at event-target")
  eventTarget.dispatchEvent(customEvent);
}
eventTarget.addEventListener('click',hello)

CustomEventコンストラクターを使って、イベントのインスタンスを作成します。

そして、イベントを付与させたい要素に通常通り、addEventListenerを使ってイベントハンドラーを設定します。

最後に、要素に対してdispatchEventでイベントを呼び出すことができます。

今回の例で言うと、クリックイベントに合わせてカスタムイベントが発火されるようになっています。

使い所はそこまで多くありませんが、知っておいて損はないでしょう。

まとめ

今回は、JavaScriptにおけるイベントハンドラーについて解説しました。

ぜひ、この記事を参考にイベントについての理解を深めてください。

宣伝

0からエンジニアになるためのノウハウをブログで発信しています。
https://hinoshin-blog.com/

また、YouTubeでの動画解説も始めました。
YouTubeのvideoIDが不正ですhttps://www.youtube.com/channel/UCqaBUPxazAcXaGSNbky1y4g

インスタの発信も細々とやっています。
https://www.instagram.com/hinoshin_enginner/

興味がある方は、ぜひリンクをクリックして確認してみてください!

Discussion