2
5

イベントの発火を操る3つのインスタンスメソッド

Posted at

イベント

イベントとはマウスクリックやドラッグ&ドロップなどユーザーの操作によって発生する動作や、Local Storageの操作のようなシステムで生じた出来事のことを指します。
JavaScriptを用いることでイベントが発火した時に特定のJavaScriptの関数を実行させられます。その関数のことをイベントハンドラと呼び、それをイベントに紐づけるように定義することをイベントハンドラを登録すると言います(イベントハンドラはJavaScriptの関数と書きましたが、厳密にはそれに限定せず実行される特定のコードブロックのことを指します)。
下の例ではbuttonというidを持つ要素をクリックしたときにアラートを出すようなイベントハンドラを登録しています。

const button = document.getElementById('button');
button.addEventListener('click', () => {
  alert('clicked')
});

addEventListenerでイベントハンドラの登録を行なっています。第1引数で登録するイベントを指定して、第2引数でイベントハンドラを記述します。

See the Pen EventHandler by KokiSakano (@kokisakano) on CodePen.

イベントハンドラではさらに、Eventインターフェイスを介してイベントのプロパティやメソッドを呼び出せます。
targetプロパティでイベントの発火元、typeプロパティでイベントの種類のように様々な情報を扱えます。例えば以下の例ではEventからtimeStampを取得してそれを表示させています。

See the Pen EventHandler by KokiSakano (@kokisakano) on CodePen.

次に下記のようなHTML構造を考えます。

- div
    - div
        - button

そして、すべての要素のクリックに対してイベントハンドラが登録されているとします。その時、buttonをクリックするとbuttonのイベントハンドラが発火し、その親のdivに登録されたイベントハンドラ、さらにその親のdivに登録されたイベントハンドラが発火します。

See the Pen Event by KokiSakano (@kokisakano) on CodePen.

この現象はバブリングと呼ばれる仕組みによって生じます。
バブリングはイベントが生じた時に、その要素のイベントハンドラを実行し、次にその親要素のイベントハンドラを実行し、さらにその親のイベントハンドラを実行するようにイベントハンドラを対象の要素から親要素へと辿って実行することを指します。
先ほどの例ではdiv→div→buttonという構造でしたので、buttonのイベントハンドラが発火、内側のdivのイベントハンドラが発火、外側のdivのイベントハンドラが発火の順で処理されました。

stopPropagation

例えばリンクによるページ遷移を行う場合にその親のクリックイベントを発火させないようにバブリングを止めたいことがあります。その時は、対象のイベントハンドラでEventを受け取ってstopPropagationを呼び出すことでバブリングを阻止できます。

const button = document.getElementById('button');
button.addEventListener('click', (e) => {
  e.stopPropagation();
  alert('clicked')
});

See the Pen stopPropagation by KokiSakano (@kokisakano) on CodePen.

stopImmediatePropagation

Eventが持つ似たようなメソッドとしてstopImmediatePropagationがあります。
stopImmediatePropagationもバブリングに関するメソッドで、stopPropagationは親要素のイベントハンドラの実行を防ぐだけだったのに対して、このメソッドはそれ以降に登録された同要素に対してのイベントハンドラの発火も防ぎます。

const button = document.getElementById('button');
// 発火する
button.addEventListener("click", () => {
  alert(1);
});
// 発火する
button.addEventListener("click", (e) => {
  e.stopImmediatePropagation();
  alert(2);
});
// 発火しない
button.addEventListener("click", () => {
  alert(3);
});

以下の例ではbuttonに対してそれぞれ2つのイベントハンドラを登録し、1つ目のイベントハンドラでそれぞれstopPropagationstopImmediatePropagationを呼び出すことで動作差分を確認できます。

See the Pen stopImmidiatePropagation by KokiSakano (@kokisakano) on CodePen.

preventDefault

ブラウザにはそれぞれのイベントに対するデフォルトの挙動が実装されています。例えばチェックボックスにはクリックすると見た目が切り替わる挙動が実装されています。
チェックボックスのクリックに対してe.preventDefaultを呼び出すイベントハンドラを登録するとその挙動が呼び出されません。

const input = document.getElementById("remove");
input.addEventListener('click', (e) => {
  e.preventDefault();
});

See the Pen EventHandler by KokiSakano (@kokisakano) on CodePen.

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5