LoginSignup
12
8

More than 3 years have passed since last update.

[JavaScript] イベントリスナーを複数同時に設定可能な関数またはメソッドを作成する

Last updated at Posted at 2019-10-08

jQuery の on の使い方に慣れていると addEventListener に同時に複数のイベントを登録したいときがあります。

通常の書き方


const target = document.querySelector("設定対象");
target.addEventListener("click", MyFunc);
target.addEventListener("keydown", MyFunc);

MyFunc の部分には自身で定義した関数を登録します。
querySelector の使い方は割愛します。

代わりの関数を作成する場合

TypeScript

const addMultipleEventListener = (element: Element | null, eventNames: string, listener: listener): void => {
    const target = element as EventTarget;
    const events = eventNames.split(" ");
    events.forEach((event: string) =>
        target.addEventListener(event, listener, false)
    );
};

JavaScript

const addMultipleEventListener = (target, eventNames, listener) => {
    const events = eventNames.split(" ");
    events.forEach(event => target.addEventListener(event, listener, false));
};

使い方

const target = document.querySelector("設定対象");
addMultipleEventListener(target, "click keydown", MyFunc);

本来の addEventListener とは使い方が若干異なります。

jQuery の on 相当のメソッドを追加する場合

Reflect.defineProperty を使用することで、
該当のメソッドが存在しない場合にオリジナルのメソッドを生やせます。

TypeScript


type listener = EventListener | EventListenerObject | null;
Reflect.defineProperty(EventTarget.prototype, "on", {
    configurable: true,
    enumerable: false,
    writable: true,
    value: function(eventNames: string, listener: listener): void {
        const target = this as EventTarget;

        const events = eventNames.split(" ");
        events.forEach((event: string) =>
            target.addEventListener(event, listener, false)
        );
    },
});

on の型定義で怒られる場合

TypeScript で Element や EventTarget に on がないと怒られる場合は型定義を拡張します。

type listener = EventListener | EventListenerObject | null;

declare global {
    interface EventTarget {
        on(eventNames: string, listener: listener): void;
    }
    interface Element {
        on(eventNames: string, listener: listener): void;
    }
}

JavaScript


Reflect.defineProperty(EventTarget.prototype, "on", {
    configurable: true,
    enumerable: false,
    writable: true,
    value: function(eventNames, listener) {
        const events = eventNames.split(" ");
        events.forEach(event => this.addEventListener(event, listener, false));
    },
});

使い方


const target = document.querySelector("設定対象");
target.on("click keydown", MyFunc);

厳密には jQuery の on よりもシンプルな実装なので、完全再現するにはもう少し手を加える必要があります。

サンプル

参考にした記事

12
8
1

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
12
8