JavaScript: カスタムイベントを使う

1. このページの目的

カスタムイベントを使ってみる。

2. 基本事項

イベントリスナーの登録

elem.addEventListener('awesome', function (e) { /* ... */ }, false);

イベントの作成と発火

// イベントの作成
const eventAwesome = new CustomEvent(
  // イベント名
  'awesome',
  // オプション
  {
    bubbles: true, // バブリングを許可
    detail: { text: () => textarea.value } // データを保持させる
  }
);

// イベントの発火
elem.dispatchEvent(event);

3. デモ

HTML (本ページ内)

<!-- ここにカスタム要素を出力する -->
<input is="my-input1">

<script type="module">
// カスタム要素用クラスをインポートして、タグ名に紐付ける
import MyInput1 from './my-input1.js';
customElements.define('my-input1', MyInput1, {extends: 'input'});

const myInput1 = document.querySelector('input[is=my-input1]'),
      demo1Output = document.querySelector('#demo1-output');
myInput1.addEventListener('keydown', function(e) {
  demo1Output.textContent = '';
});
// カスタムイベントにリスナーを登録する
myInput1.addEventListener('b-input', function(e) {
  demo1Output.textContent = `"b" が入力されました!(${e.detail})`;
});
</script>

JavaScript (my-input1.js)

export default class extends HTMLInputElement {
  constructor() {
    super();

    this._onInput = this._onInput.bind(this);
    this.addEventListener('input', this._onInput);

    // カスタムイベントリスナーを登録する
    this._onBInput = this._onBInput.bind(this);
    this.addEventListener('b-input', this._onBInput, false);
  }

  disconnectedCallback() {
    this.removeEventListerm('b-input', this._onBInput);
  }

  _onInput(e) {
    const c = e.data;
    if (c == 'b') {
      // イベントを作成
      const event = new CustomEvent('b-input', {
        bubbles: true,
        detail: 'イベントに保持された値' // object をセットすることも可能
      });
      // イベント発火!
      this.dispatchEvent(event);
    }
  }

  _onBInput(e) {
    console.log(e);
  }
};

実行結果

以下の <input> 要素には、'b' が入力されたときだけ発火するイベントが設定してある。

4. メモ

参考