15 Event - iruma-tea/dokushujs GitHub Wiki

15. イベント

JavaScriptでは、何らかの契機でブラウザから発生した通知をイベントとして受け取る。
イベントには、クリック操作やスクロール操作、フォームへの入力などのユーザー起因のイベントや画面ロードの完了などの
ブラウザ起因のイベントがある。
JavaScriptでイベントの発生を検知し、何らかの処理を実行するには、イベントが発生したときに実行される関数(アクションと呼びます)をイベントハンドラまはた、イベントリスナに登録する。

JavaScriptでイベントを登録する2つの方法

  • イベントハンドラにアクションを登録する。
  • イベントリスナにアクションを登録する。

15.1 イベントハンドラ

15.1.1 イベントハンドラの登録

イベントハンドラとは、イベントが発生したときに実行される関数(アクション)のこと。
Windowオブジェクト(window)、Elementオブジェクト、Documentオブジェクト(document)などのonから始まるプロパティに対して、
アクションを設定することで、イベント発生時に特定の処理を実行できる。

[構文]イベントハンドラの登録方法
EventTarget.on{イベントタイプ}=action;

EventTarget: この要素でイベントが発生したときに、登録された関数(action)が実行される。Elementオブジェクト、window、documentなどが使用可能。

on{イベントタイプ}: イベントタイプにはclickなどが入る。例えば、 クリックイベントの場合はonclickになる。

action: イベント発生時に実行したい関数を登録する。名前付き関数、または無名関数、アロー関数を登録できる。   
また、actionの第一引数はEventオブジェクトが渡される。
 クリック操作を検知するイベントハンドラの登録

<div>
    <button id="minus">-</button>
    <span id="number">0</span>
    <button id="plus">+</button>
    <script>
        let count = 0;
        // Elementの取得
        const number = document.querySelector("#number");
        const plusBtn = document.querySelector("#plus");
        const minusBtn = document.querySelector("#minus");

        plusBtn.onclick = function(event) {
            count++;
            number.textContent = count;
        };

        minusBtn.onclick = function(event) {
            count--;
            number.textContent = count;
        };
    </script>
</div>

15.1.2 イベントハンドラの解除

イベントハンドラをnullで初期化することによって、登録したアクションを解除できる。

[構文]イベントハンドラの解除方法
EventTarget.on{イベントタイプ} = null;
 ボタンに登録したアクションを解除
<button>アラート</botton>

<script>
    const btn = document.querySelector("botton");
    btn.onclick = function() {
        alert("アラート!");
    }

    btn.onclick = null;
</script>

15.2 イベントリスナ

イベントリスナとはイベントにアクションを紐づける仕組みのこと
イベントが発火するとイベントに登録されたアクションが実行される点はイベントハンドラと同じであるが、
次の3つの点が異なる。

  • オプション指定が可能
    • アクションが実行される条件をオプションで指定できる。
  • 複数のアクション(関数)の登録が可能
    • 複数のアクションを個別に登録できる。
  • アクション毎に登録解除が可能
    • 複数のアクションを個別に解除できる。

15.2.1 イベントリスナの登録

イベントリスナを登録するには、addEventListenerメソッドを使う。

[構文] イベントリスナとアクション(関数)を登録
EventTarget.addEventListener("イベントタイプ",action[,options]);

EventTarget: この要素でイベントが発生するときに、登録された関数(action)が実行される。Elementオブジェクトやwindow、documentなどが使用可能です。     

"イベントタイプ": イベントタイプを文字列を入力する。onは先頭につかない。例えば、クリックイベントの場合、clickとなる。

action: イベント発生時に実行したい関数を登録する。名前付き関数、無名関数、アロー関数を登録できる。また、actionの第一引数には、Eventオブジェクトが渡される。

options: optionsではイベントリスナの挙動の設定を行うことができる。真偽値またはオブジェクトを設定可能。()

(※) optionsのプロパティ

プロパティ 説明
capture 登録されたアクションをキャプチャリングフェーズで実行する。デフォルトはfalse。
once アクションの実行を一度きりとする場合にtrueを渡す。実行後は自動的にアクションは削除される。デフォルトはfalse。
passive trueとした場合には、パッシブリスナが有効になる。パッシブリスナが有効な状態では、アクション内で呼び出されるEvent.preventDefaultはブラウザのデフォルト処理を停止しない。
<div>
    <button id="minus">-</button>
    <span id="number">0</span>
    <button id="plus">+</button>
</div>
<script>
    let count = 0;

    // Elementの取得
    const number = document.querySelector("#number");
    const plusBtn = document.querySelector("#plus");
    const minusBtn = document.querySelector("#minus");

    plusBtn.addEventListener("click", function(event) {
        count++;
        number.textContent = count;
    });

    minusBtn.addEventListener("click", function(event) {
        count--;
        number.textContent = count;
    });
</script>

15.2.2 複数のイベントリスナを登録

イベントリスナを使うと、複数のアクションをイベントに紐づけることができる。
なお、イベントハンドラに直接登録するときは関数を一つのしか登録できない。

 複数のアクションをイベントリスナとして登録
<div>この要素の色が変わります。</div>
<button id="color">文字色の変更</button>
<button id="bg-color">背景色の変更</button>
<button id="all-color">文字色と背景色の変更</button>
<button id="reset-color">リセット</button>

<script>
    const targetEl = document.querySelector("div");
    const colorBtn = document.querySelector("#color");
    const bgColorBtn = document.querySelector("#bg-color");
    const allColorBtn = document.querySelector("#all-color");
    const resetBtn = document.querySelector("#reset-color");

    function colorChange(event) {
        targetEl.style.color = "#ff0000";
    }

    function bgColorChange(event) {
        targetEl.style.backgroundColor = "blue";
    }

    function reset(event) {
        targetE1.style.backgroundColor = "";
        targetE1.style.color = "";
    }

    colorBtn.addEventListener("click", colorChange);
    bgColorBtn.addEventListener("click", bgColorChange);
    allColorBtn.addEventListener("click", colorChange);
    allColorBtn.addEventListener("click", bgColorChange);
    resetBtn.addEventListener("click", reset);
</script>

15.2.3 イベントリスナの解除

removeEventListenerメソッドを使用することで、登録したアクションの解除を行う。

[構文]removeEventListenerの記法
EventTarget.removeEventListener("イベントタイプ", action);

EventTarget : addEventListenerでイベントリスナの登録時に渡した要素と同じ要素を指定する。
action: addEventListenerでイベントリスナの登録時に渡したのと同じ関数への参照を渡すことで、その関数をイベントリスナの対象から除外する。
 アクション解除の例
<div>色は変わりません。</div>
<button id="color">文字色の変更</button>

<script>
    const targetEl = document.querySelector("div");
    const colorBtn = document.querySelector("#color");

    function colorChange(evnet) {
        targetEl.style.color = "#ff0000";
    }

    colorBtn.addEventListener("click", colorChange);
    colorBtn.removeEventListener("click", colorChange);
</script>

◇ HTMLの属性にアクションを登録する方法(非推奨)

<button onclick="alert('ボタンがクリックされました。')">ボタン</button>

ただし、この方法ではHTMLファイル内にJavaScripコードを記述するため、プロジェクトが大きくなってくると、
コードを整理するのが困難になってくるため、基本的にはイベントハンドラやイベントリスナに対してアクションを追加する。

15.3 イベントの伝播

ページ内のどこかの要素でイベントが発生した場合にはイベントが要素間を伝播して行きます。これをイベントの伝播と呼びます。   イベントの伝播は、キャプチャリングフェーズ、ターゲットフェーズ、バブリングフェーズの3つに分けることができる。
HTML内の要素でイベントが発生した場合には、これら3つのフェーズが順番に実行される。

15.3.1 キャプチャリングフェーズ(Capturing Phase)

イベントの伝番で最初に発生するのフェーズ。キャプチャリングフェーズでは、発生したイベントと同じタイプのイベント(例えば、クリックイベント)が上位から下位へ伝播していく。
具体的にはHTML内の何れかの要素でイベントが発生した場合には、最上位のWindowオブジェクトからイベントの伝播が始まり、Documentオブジェクト、要素の順でイベントが発生した要素まで同じイベントが順番に伝わっていく。

キャプチャーリング

なお、イベントハンドラやイベントリスナで登録したアクションは、キャプチャリングフェーズでは 一般的には実行されない。
イベントリスナのオプションで{capture: true}を設定したアクションのみ、このフェーズが実行される。

// キャプチャリングの確認
<!DOCTYPE html>
<html>
    <body>
        <div id="div1"></div>
        <div id="div2">
            <button>ボタン</button>
        </div>
        <script>
            const div1 = document.querySelector("#div1");
            const div2 = document.querySelector("#div2");
            const button = document.querySelector("#button");

            // windowオブジェクトにclickイベントを登録
            window.addEventListener("click", () => {
                console.log("windowのclickイベント");
            },{capture: true});

            // div1にクリックイベントを登録
            div1.addEventListener("click", () => {
                console.log("div1のclickイベント");
            }, {capture: true});

            // div2にクリックイベントを登録
            div2.addEventListener("click", () => {
                console.log("div2のclickイベント");
            }, {capture: true});

            // buttonにclickイベントを登録
            button.addEventListener("click", () => {
                console.log("buttonのclickイベント");
            }, {capture: true});
        </script>
    </body>
</html>

・ボタンクリック後のログ
> windowのclickイベント
> div2のclickイベント
> buttonのclickイベント

15.3.2 ターゲットフェーズ(Target Phase)

キャプチャリングフェーズによって、イベントの伝播がイベントが発生した要素までたどり着くと、
ターゲットフェーズになる。このフェーズではイベントが発生した要素に登録しているアクションを実行する。

ターゲットフェーズ

15.3.3 バブリングフェーズ(Bubbling Phase)

ターゲットフェーズが完了すると、今度はイベントが上位の親要素、祖先要素に対してイベントの伝播が起こります。
これをバブリングフェーズと呼ぶ バブリングフェーズ バブリングフェーズでは、親要素、祖先要素、doucment、windowで同じイベントタイプに登録されているアクションが実行される。
また、イベントリスナに{capture:true}が設定されているアクションは、キャプチャリングフェーズで、すでに実行済みのため実行されない。
イベントリスナに{capture:true}をつけていない場合には、バブリングによってイベント伝播によるアクションの実行を行う。

 バブリングの確認
<!DOCTYPE html>
<html>
    <body>
        <div id="div1"></div>
        <div id="div2">
            <button>ボタン</button>
        </div>
        <script>
            // Element オブジェクトの取得
            const div1 = document.querySelector("#div1");
            const div2 = document.querySelector("#div2");
            const button = document.querySelector("button");

            // windowにclickイベントを登録(caputer:trueとして登録)
            window.addEventListener("click", () => {
                console.log("windowのclickイベント");
            }, {capture: true});

            // div2にclickイベントを登録
            div2.addEventListener("click", () => {
                console.log("div2のclickイベント");
            });

            // buttonにclickイベント
            button.addEventListener("click", () => {
                console.log("buttonのclickイベント");
            });
        </script>
    </body>
</html>

ボタンクリック後のログ
> windowのclickイベント
> buttonのclickイベント
> div2のclickイベント

一部のイベントタイプ(例えば、mouseleaveやfocus)では、バブリングは発生しない。
また、バブリングが発生するかどうかはEventオブジェクトのbubblesプロパティがtrueかどうかで判定できる。

15.4 Eventオブジェクト

イベントハンドラやイベントリスナに登録した関数の引数に渡されるEventオブジェクトについて記載する。

[構文]Eventオブジェクト

EventTarget.on{イベントタイプ} = function(event) {...}
EventTarget.addEventListener("イベントタイプ", function(event) {...});

event: Eventオブジェクト。このEventオブジェクトは、Eventコンストラクタを継承した別のコンストラクタから
インスタンス化されたオブジェクトです。
例えば、inputイベントなどに登録したアクションには、Eventコンストラクタを継承したInputEventコンストラクタから
生成されたオブジェクトが渡される。そのため、イベントタイプによってアクセス可能なプロパティが変わる。

Eventオブジェクトには、イベントの発生状況に関わる情報が格納されている。
Eventオブジェクトに設定されるプロパティはイベントタイプによって変わるが、以下はどのイベントタイプでも
使用できる共通のプロパティとメソッド。

メソッド 説明
preventDefault() ブラウザのデフォルト処理の実行を抑止する抑止可能なイベントタイプはcancelableがtrueのイベント
stopPropagation() キャプチャリング、バブリングによるイベント伝播を抑止する。
stopImmediatePropagation() stopPropagation()の作用に加え、自要素に対して複数のアクションが登録されている場合は、後続のアクションの実行を抑止する。
プロパティ 説明
type イベントタイプが文字列で渡される(例:click)
cancelable preventDefault()を使って、デフォルト処理をキャンセル可能かどうかを返す(true/false)。trueの場合、キャンセル可能
bubbles 発生中のイベントでバブリングが発生するかどうかを返す。trueの場合、バブリングが発生する。
currentTarget アクションを登録した(ターゲット)要素を返す。キャプチャリングやバブリングが発生しているときも、常にアクションを登録した要素を返すことに注意。
target **実際にイベントが発生した要素を返す。**キャプチャリング、バブリングの作用によって実際にイベントが発生した要素とアクションが登録されている要素が異なる可能性に注意。
defaultPrevented preventDefault()によって、ブラウザのデフォルト処理がキャンセルされたかどうかを表す。(true/false) trueの場合、キャンセルされた状態を表す。
eventPhase 実行中のイベントフェーズを表す(※)
timestamp ドキュメントの生成からイベントの発生までの時間を返す。
isTrusted イベントがユーザー操作によって発生したものか、スクリプトによって発生したものかを判定する。(true/false)。ユーザー操作によって発生した場合、true

(※) 実行中のイベントフェーズを表す。

数値(定数) 説明
0 (Event.NONE) 実行中のイベントがない状態
1 (Event.CAPTURING_PHASE キャプチャリングフェーズ
2 (Event.AT_TARGET) ターゲットフェーズ
3 (Event.BUBBLING_PHASE バブリングフェーズ

15.4.1 他の要素への伝播を停止(stopPropagation)

stopPropagationメソッドを呼び出すことで、他の要素への伝播を止めます。
キャプチャリングフェーズで呼び出された場合、下位の要素に設定されているアクションが実行されることはない。
stopPropagetion

ターゲットフェーズ、バブリングフェーズで呼び出された場合には、上位の要素にイベント伝播しない。 stopPropagetion

 キャプチャリングフェーズでイベント伝播を停止した場合

<section>
    section <br />
    <div>
        div <br />
        <button>button</button>
    <div>
    <p>p<br />この要素は伝播の対象外です。</p>
<section>
<style>
    section, div, p, button {
        padding: 10px;
        border: 10px solid skyblue;
    }
</style>
<script>
    const button = document.querySelector("button");
    const div = document.querySelector("div");
    conse section = document.querySelector("section");

    // buttonに対するアクションを登録
    button.addEventListener("click", (event) => {
        console.log("buttonのclickイベントが実行されました。");
    });

    // divに対するアクションを登録
    div.addEventListener("click", (event) => {
        console.log("divのclickイベントが実行されました。");
    });

    // sectionに対するアクションを登録
    section.addEventListener("click", (event) => {
        event.stopPropagation();
        console.log("sectionのclickイベントが実行されました。");
    },{capture: true}); // キャプチャリングフェーズでアクションを実行
</script>

ボタンをクリック後のログ
> sectionのclickイベントが実行されました。 
div buttonのアクションは実行されない!

15.4.2 アクションを即時で停止(stopImmediatePropagation)

同じ要素に複数のアクションが登録されていた場合、後続のアクションへの伝播も止めたいときには、stopImmediatePropagationを使う。
stopImmediatePropagationでは実行中のアクションが完了するとイベント伝播は即時で終了する。

Event.stopImmediatePropagationの使用例

<div>この要素の色が変わります。</div>
<button id="all-color">文字色と背景色の変更</button>
<script>
    const targetEl = document.querySelector("div");
    const allColorBtn = document.querySelector(""all-color);

    // 文字色を変更するアクション
    function colorChange(event) {
        event.stopImmediatePropagation(); // 後続のアクションへのイベント伝播を停止
        targetEl.style.color = "#ff0000";
    }

    // 背景色を変更するアクション
    function bgColorChange(event) {
        targetEl.style.backgroundColor = "blue";
    }

    // 関数を2つ登録
    // アクションは登録された順番(colorChage → bgColorChange)で実行される。
    allColorBtn.addEventListener("click", colorChange);
    allColorBtn.addEventListener("click", bgColorChange);
</script>

15.4.3. ブラウザのデフォルト処理を止める場合(preventDefault)

HTMLタグによっては、ブラウザの特定の処理が実装されている場合がある。    例えば、アンカータグ(a)はリンクを作成するときに使いますが、このタグがクリックされた場合には、
ブラウザのデフォルト処理によって、リンク先URLに画面遷移する。
これらのブラウザのデフォルト処理を止めるには、preventDefaultをアクション内で実行する。

 すべてのリンクの機能を無効化する
<a href="https://www.google.com">Googleへは行かせません。</a>
<a href="https://www.yaoo.co.jp">Yahooへは行かせません。</a>

<script>
    // すべてのアンカータグ(a)を取得する
    const links = document.querySelector("a");

    // すべてのアンカータグに対してリンク無効化のアクションを追加
    links.forEach(link => link.addEventListener("click", evnet => {
        event.preventDefault();
        alert(event.currentTarget.textContent); // アラートの表示
    }))
</script>

15.4.4 tagetとcurrentTargetの違い

EventオブジェクトのtargetとcurrentTargetには異なる要素が格納される場合があるため、注意が必要。
これはバブリングの作用によって起こる。

<body>
    <section id="container">
        <button>ボタン</button>
    </section>
    <script>
        // #container(sectionタグにアクションを登録する)
        const containerEl = document.querySelector("#container");

        containerEl.addEventListener("click", function(event) {
            console.log(`currentTarget: [ ${event.currentTarget.nodeName} ]`);
            console.log(`target: [ ${event.target.nodeName} ]`);
        });
    </script>
</body>

ボタンクリック後

> currentTarget:[SECTION]
> target:[BUTTON]

buttonをクリックするとbuttonタグでclickイベントが発生する。このとき、target、currentTargetでは異なる要素が取得される。
currentTargetの場合は常に実行中のアクションが登録された要素が取得される。targetの場合イベントが発生した要素が取得される。 targetとcurrentTargetの違い バブリングによってイベントが発生した要素と実行中のアクションが登録された要素が異なる場合には、それぞれ取得される要素が異なるため、注意が必要。

15.5 イベントの補足事項

パッシブリスナやイベントをスクリプトから実行する方法を紹介する。

15.5.1 パッシブリスナ

**パッシブリスナ(Passive Listener)**とはChrome51より導入されたスクロールのパフォーマンスを改善する仕組みです。
addEventListenerのオプションに{passive:true}を渡すことで、パッシブリスナが有効になる。
これにより、アクション内でのEvent.preventDefault()の実行を無効化します。
なお、Chromeの場合はデフォルトが{passive:true}です。

 スクロール処理を禁止する
<body>
    <div></div>
    <style>
        body {
            margin: 0px;
        }
        div {
            background: liner-gradient(#e66456, #9198e5);
            height: 200vh;
        }
    </style>

    <script>
        function preventScroll(event) {
            event.preventDefault();
        }

        document.addEventListener("touchmove", preventScroll, {passive: false});
        document.addEventListener("wheel", preventScroll, {passive: false});
    </script>
</body>

15.5.2 イベントをスクリプトから実行

ユーザーの画面入力によって発生するclickイベントやinputイベントなどをJavaScriptのコードから発火する方法を記載する。
コードからイベントを発火するには、dispatchEventメソッド使用する

[構文] dispatchEventの記法
let cancelled = EventTarget.dispatchEvent(event);

EventTarget: イベントを発生させたい要素を設定する。Elementやwindow,documentなど。
event: 発火したいイベントタイプのEventオブジェクトを渡す。Eventオブジェクトは、new Event("イベントタイプ"[, {bubbles: true}])
形式でインスタンス化する。(第二引数{bubbles: true}を省略した場合、バブリングは発生しない。)
cancelled : イベントで発火により実行されたアクションの中でEvent.preventDefaultが1回でも実行された場合にfalseが返る。それ以外はtrueを返す。
clickイベントをコードから発火

<span>0</span>
<button disabled>+</button>

<script>
    const button = document.querySelector("button");
    const span = document.querySelector("span");

    let count = 0;

    button.addEvenListener("click", fuction(event) {
        count++;
        span.textContent = count;
    });

    // Eventオブジェクトのインスタンス化
    const myEvent = new Event("click");

    // 1秒間隔でclickイベントを発火
    setInterval(() => {
        button.dispatchEvent(myEvent); // イベントを発火
    }, 1000);

</script>

15.5.3 様々なイベント

  • キーボード操作に関するイベント
    イベントタイプ 発火タイミング
    input <input>要素のvalue属性や<textarea>のコンテンツが変化するたびに発火する。
    change <input>要素のvalue属性の値や<teaxtarea>のコンテンツ値が確定したタイミングで発火する。
    keydown 任意のキーが押し込まれたときに発火する。
    keypress
    非推奨
    変わりにkeydownイベントを使用する。
    keyup 任意のキーを離すタイミングで発火する
    compositionstart IMEによる編集セッションが開始したタイミングで発火する。
    compositionend IMEによる編集セッションが終了したタイミングで発火する。
    compositionupdate IMEによる編集セッション中で文字が追加されたときに発火する。
    submit フォームが送信されたときに発火する
  • マウス操作に関するイベント
    イベントタイプ 発火タイミング
    click マウスの左クリックが押されたときに発火する。
    dbclick マウスの左クリックが2回連続されたときに発火する。
    contextmenu コンテキストメニューを開くときに発火する。
    mousedown マウスでクリックされたときに発火する。左クリック、右クリックどちらでも発火する。
    mouseup マウスのクリックが離されるときに発火する。左クリック、右クリックどちらでも発火する。
    mouseenter カーソルが要素内に入るタイミングで発火する。バブリングは発生しない
    mouseover カーソル要素、またはその子要素を通過するときに発火する。バブリングは発生しない。
    mousemove カーソルが要素内で移動している間に連続的に発火する。バブリングは発生しない。
    mouseleave カーソルが要素から出たときに発火する。バブリングは発生しない。
    mouseout カーソルが要素から出たときに発火する。バブリングは発生しない。
  • カット、コピー、ペーストなどに関わるイベント
    イベントタイプ 発火タイミング
    copy コピー操作を行ったときに発火する。
    paste ペースト操作を行ったときに発火する。
    cut カット操作を行ったときに発火する。
  • フォーカスに関するイベント
    イベントタイプ 発火タイミング
    focusin 要素にフォーカスが当たったときに発火する。バブリングは発生する。
    focus 要素にフォーカスが当たったときに発火する。バブリングは発生しない。
    focusout 要素からフォーカスが外れたときに発火する。 バブリングは発生する。
    blur 要素からフォーカスが外れたときに発火する。 バブリングは発生しない。
  • スクロールや画面タッチに関わるイベント
    イベントタイプ 発火タイミング
    scroll 画面がスクロースしている間は連続的に発火する。
    wheel マウスのホイールが回転している間は連続的に発火する。
    mousewheel
    非推奨
    代わりにwheelイベントを使用する。
    touchstart スマホのタッチ入力が開始されたタイミングで発火する。
    touchmove スマホのタッチ操作が継続している間は連続的に発火する。
    touchend スマホのタッチ入力が終了したタイミングで発火する。
  • アニメーションに関わるイベント
    イベントタイプ 発火タイミング
    transitionstart CSSのtransitionプロパティによるアニメーション開始時に発火する。 トランジションの遅延(transition-deley)を待ってから発火する。
    transitionrun CSSのtransitionプロパティによるアニメーション開始時に発火する。 トランジションの遅延(transition-deley)を待たずに発火する。
    transitionend CSSのtransitionプロパティによるアニメーション終了時に発火する。
    animationstart CSSのanimationプロパティによるアニメーション開始時に発火する。アニメーションの遅延(animation-deley)を待ってから発火する。
    animationend CSSのanimationプロパティのよるアニメーション終了時に発火する。
    animationiteration CSSのanimationプロパティによるアニメーションが1回ループしたタイミングで発火する。
  • 画面(window)に関わるイベント
    イベントタイプ 発火タイミング
    load CSS(.css)/JS(.js)ファイル、画像などのHTMLから読み込んでいるすべてのリソースが読み込み完了した時点で発火する。
    DOMContentLoaded DOMツリーの構築が完了した時点で発火する。DOM操作が行える状態になったことを表す最初のイベント。
    CSS(.css)/JS(.js)ファイル、画像などの読み込みは完了していない可能性がある。DOCUMENTオブジェクトに対するイベントリスナとして登録可能
    readystatechange Documentオブジェクトに登録可能なイベントタイプ。画面の読み込みフェーズが変わったタイミングで発火する。
    readyStateプロパティによって、現在どのフェーズであるか判断できる(※)
    beforeunload 現在表示中のページがアンロードされる直前に発火する。
    unload 現在表示中のページがアンロードされたときに発火する。
    resize 画面サイズが変更されたときい発火する。
    online ブラウザがネットワーク接続の検知したタイミングで発火する。
    offline ブラウザがネットワーク接続の切断を検知したタイミングで発火する。

(※) document.readyStateプロパティの値

説明
loading 画面ロード中、DOMツリーの構築も完了していない
interactive DOMツリーの構築が完了している。(DOMContentLoadedと同じ状態)
complate loadイベントの直前に発火する。HTMLおよびHTMLで読み込んでいるリソース(CSS/JSファイル、画像など)の読み込みも完了している。
⚠️ **GitHub.com Fallback** ⚠️