25. イベントリスナー

イベントリスナー

onclickonchangeのようなHTMLプロパティでイベント登録しましたが、JavaScriptのオブジェクトに対してイベント登録ができます。

addEventListener()

addEventListener() は、JavaScriptでイベントリスナー(イベントハンドラ)を登録するためのメソッドです。

element.addEventListener(eventType, callback, options);
引数 説明
elementType イベントのタイプ click, change, mouseoverなど
callback イベントが発生したときに実行されるコールバック関数
options オプション設定を含むオブジェクト capture, onceなど

イベントタイプの種類

イベント名(JS) (HTML) 説明
load onload ページが読み込まれたとき
click onclick クリックされたとき
dblclick ondblclick ダブルクリックされたとき
input oninput 値が入力されたとき
submit onsubmit submitボタンが押されたとき
change onchange 内容が変更されたとき
keypress onkeypress キーボードキーが押されたとき
focus onfocus ターゲットが選択された時
mouseup onmouseup ターゲット内でマウスをアップしたとき
mouseover onmouseover マウスカーソルがターゲットの中に入ったとき
mousemove onmousemove マウスカーソルがターゲットの中に移動したとき
drag ondrag ドラッグされたとき
scroll onscroll スクロール位置が変更されたとき

イベントのコールバック関数

addEventListener() の第2引数はコールバック関数を指定します。コールバック関数の引数はeventオブジェクトが代入されます。

//コールバック関数の引数は、eventオブジェクト
element.addEventListener(eventType, function(event) {

});

preventDefault

preventDefaultは、JavaScriptのイベントのデフォルトの動作をキャンセルするためのメソッドです。イベントが発生したときに、通常はブラウザがデフォルトの動作を実行しますが、preventDefaultを呼び出すと、その処理を中止できます。

element.addEventListener(eventType, function(event) {
    //処理
    event.preventDefault();    //処理中止
});

オプション

addEventListener() の第3引数は、イベント動作のオプションを指定します。

プロパティ 説明
capture イベントキャプチャを使用するかどうかを指定 デフォルト:false
once イベントが一度だけ実行 デフォルト:false
passive preventDefault を呼び出しても、動作を行わないことを指定 デフォルト:false

capture

captureは、イベントの伝播フローを制御するためイベントキャプチャ(Event Capture)設定です。

バブリングフェイズ

capturefalseのときバブリングフェーズとなり、デフォルトの設定です。子要素で発生したイベントが親要素にも影響を及ぼします。

element.addEventListener(eventType, callback, false);
//または
element.addEventListener("click", myFunction, { capture: false });
キャプチャフェーズ

capturetrueのとき、キャプチャフェーズとして親要素から子要素に向かってイベントが伝播します。

element.addEventListener(eventType, callback, true);
//または
element.addEventListener("click", callback, { capture: true });

passive

通常ブラウザはイベントハンドラ内で行われる処理が終わるまでイベントが待機しますが、一部イベント(特にスクロールイベント)は、イベント処理が長時間かかるとスクロールの滑らかさに影響します。passiveでスクロールのパフォーマンスが向上することがあります。

イベント登録

addEventListener() で、ボタンにクリックイベントを登録してみましょう。

入力フォーム作成

listener.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Calculate</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>

<body>
  <main class="container">
    <h2>合計金額</h2>
    <p id="result"></p>
    <h2>データ入力</h2>
    <form action="" method="post">
      <div>
        <label class="form-label" for="price">価格</label>
        <input class="form-control" type="text" id="price" name="price"><br>
      </div>
      <div>
        <label class="form-label" for="price">個数</label>
        <input class="form-control" type="number" id="quantity" name="price"><br>
      </div>
      <button id="calculate-btn" class="btn btn-primary">計算</button>
    </form>
  </main>

  <script src="js/listener.js"></script>
</body>

</html>

計算処理

listener.js
    const calculateBtn = document.getElementById('calculate-btn');
    calculateBtn.addEventListener('click', function (event) {
    }, false);
listener.js
    const calculateBtn = document.getElementById('calculate-btn');
    calculateBtn.addEventListener('click', function (event) {
        const price = document.getElementById('price').value;
        const quantity = document.getElementById('quantity').value;

        var message = "入力が間違っています";
        if (!isNaN(price) && !isNaN(quantity)) {
            const totalPrice = price * quantity;
            message = "合計金額は" + totalPrice + "円です。";
        }
        document.getElementById('result').innerHTML = message;
        event.preventDefault();
    }, false);

DOMContentLoaded

window.onload

window.onload はページのすべてのリソース(画像、スタイルシート、スクリプトなど)が完全に読み込まれ、ページ全体が完全に準備されてからコードが実行されるのを待ちます。

DOMContentLoaded

DOMContentLoaded はHTMLドキュメントのパースが完了し、DOMツリーの構築が終了した直後に発生します。リソースの読み込みを待つ必要はありません。

document.addEventListener("DOMContentLoaded", callback);
listener.js
document.addEventListener("DOMContentLoaded", function () {
    const calculateBtn = document.getElementById('calculate-btn');
    calculateBtn.addEventListener('click', function (event) {
        const price = document.getElementById('price').value;
        const quantity = document.getElementById('quantity').value;

        const result = document.getElementById('result');
        var message = "入力が間違っています";
        if (!isNaN(price) && !isNaN(quantity)) {
            const totalPrice = price * quantity;
            message = "合計金額は" + totalPrice + "円です。";
        }
        result.innerHTML = message;
        event.preventDefault();
    }, false);
});

イベント削除

removeEventListener()

removeEventListener() は、addEventListener() で登録したイベントリスナーを削除するメソッドです。イベントタイプとイベントハンドラーを引数とします。

element.removeEventListener(eventType, eventHandler)

カウンター作成

【count】をクリックしてカウントアップし、【イベント削除】をクリックしたらカウントアップを無効にします。

listener.html
    <div class="mt-3">
      <h2>Remove Event</h2>
      <p id="count"></p>
      <button id="count-btn" class="btn btn-outline-primary">count</button>
      <button id="remove-btn" class="btn btn-outline-primary">イベント削除</button>
    </div>
listener.js
    var count = 0;
    const countBtn = document.getElementById('count-btn');
    const removeBtn = document.getElementById('remove-btn');
    //イベントハンドラー
    const countHandler = function () {
        document.getElementById('count').innerHTML = count++
    }
    countBtn.addEventListener('click', countHandler);
    //イベント削除のclickイベント
    removeBtn.addEventListener('click', function() {
        // カウントのclickイベント削除
        countBtn.removeEventListener('click', countHandler)
        document.getElementById('count').innerHTML = "イベントを停止しました"
    });

イベントが削除されると、【count】をクリックしても動作しません。

結果

マウスイベント

マウスオーバーとマウスアウトイベントを登録します。

listener.html
    <div class="mt-3">
      <h2>マウスイベント</h2>
      <div id="mouse-area" class="area">ここにマウスをあてる</div>
    </div>
calculate.css
.area {
    margin: 10px;
    padding: 20px;
    background-color: powderblue;
}
結果
listener.js
var mouseArea = document.getElementById('mouse-area')
mouseArea.addEventListener('mouseover', function (event) {
    this.innerHTML = 'マウスオーバー'
})

mouse_area.addEventListener('mouseout', function (event) {
    this.innerHTML = 'マウスアウト'
})

マウスの座標を取得

マウスの移動イベントで座標を取得してみましょう。

listener.html
<div id="mouse-move-area" class="area">ここにマウスをあてる</div>
listener.html

イベントハンドラ(コールバック関数)の引数eventは、イベントが発生した時にできた変数です。mousemoveイベントの場合は、マウスの座標のデータが含まれています。

var mouseMoveArea = document.getElementById('mouse-move-area')
mouseMoveArea.addEventListener('mousemove', function (event) {
    var message = `(x, y) = (${event.pageX} ${event.pageY})`
    this.innerHTML = message
})
結果

キーボードイベント

キーボードイベントは、キーボードが押された時に動作するイベントです。

キーボードイベント取得

keydownイベントで、キーボードのキーコードを取得してみましょう。

listener.html
    <div class="mt-3">
      <h2>キーコード</h2>
      <p id="keycode-area" class="area"></p>
    </div>
listener.js
keydownEvent = (event) => {
    console.log(event.keyCode)
    document.getElementById('keycode-area').innerHTML = event.keyCode;
}

document.addEventListener('keydown', keydownEvent);
  • キーコードは、eventオブジェクトのkeyCode プロパティ
結果

演習

問題1

テキストボックスに入力した文字を、任意のHTMLの場所にリアルタイムで表示してみましょう。

問題2

矢印キー(上下左右)を押している間、キャラクターを動かしてみましょう。