質問: 閲覧者が起こしたクリックや頁遷移などの行動によって実行される処理をイベントハンドラ或いはイベントリスナ―と呼びますが、この二つの単語とイベントドリブンの違いは何ですか。 イベントドリブンも発生したイベントによって実行される処理を意味するみたいです。
回答: ### イベントドリブン(event-driven) あるイベントが発動した時に対応するイベント命令(イベントハンドラ、イベントリスナ)を呼び出す仕組みの事です。 JavaScript の世界では「DOM Events」「UI Events」を指します。 * Document Object Model (DOM) Level 3 Events Specification 1.0 * UI Events (日本語訳) ### イベントリスナ(event listener) DOM Standard(日本語訳) では下記のフィールドからなるものを「イベントリスナ」としています。 * イベントタイプ (`type`) * コールバック関数 (`callback`) * キャプチャリングフェーズを使用するかの真偽値 (`capture`) * デフォルトアクションをキャンセルするかの真偽値(`passive`) * イベントリスナを削除するかの真偽値(`removed`) DOM Standard では上記フィールドからなるイベントリスナを「リスナリスト」に登録して管理しています。 ### イベントハンドラ(event handler) **addEventListener のイベントハンドラ** `addEventListener` において第2引数に指定可能なオブジェクト(EventListener インターフェースを実装するオブジェクト)です。 UI Events では「EventListener インタフェースを実装する利用者オブジェクトであって `handleEvent()` コールバックメソッドを提供するもの」としていますが、その後で「注記: JavaScript においては、利用者定義の関数は, EventListener インタフェースを実装するものと見なされる。 したがって、その関数の呼び出し時には,その最初の引数にイベントオブジェクトが渡されることになる。 加えて、 JavaScript オブジェクトは, handleEvent メソッドを定義して EventListener インタフェースを実装することもできる。」ともある為、`handleEvent()` を持たなくてもイベントハンドラと呼称できます。 * イベントハンドラ ( event handler )- UI Events (日本語訳) ``` fuction handleClick (event) { console.log(event.type); } element.addEventListener('click', handleClick, false); // handleClick がイベントハンドラ element.addEventListener('click', {handleEvent: handleClick}, false); // {handleEvent: handleClick} がイベントハンドラ ``` **atattchEvent のイベントハンドラ** IE8- 全盛期時代では IE8- が `addEventListener` をサポートしなかった為、`attachEvent` を併用して実装されました。 MSDN では `attachEvent` の第2引数を `pDisp` であり、`pDisp`を「イベントハンドラが呼び出されるより前に呼び出される関数」と定義しています。 .NET Framework では `attachEvent` の第2引数を `System.EventHandler` 型の `handler` としており、「イベントハンドラ関数」と呼称しても概ね問題ないと思います。 * attachEvent method (Internet Explorer) * HtmlObject.AttachEvent メソッド (String, EventHandler) (System.Windows.Browser) ``` fuction handleClick (event) { console.log(event.type); } if (element.addEventListener) { element.addEventListener('click', handleClick, false); // handleClick がイベントハンドラ } else if (element.attachEvent) { element.attachEvent('onclick', handleClick); // handleClick がイベントハンドラ } ``` **HTML 要素のイベントハンドラ** 更に古くは要素自身が持つ `onclick` イベントハンドラ等を利用して実装されました。 これは長らく標準化されてきませんでしたが、HTML5 (HTML Living Standard)で標準化され、今でも使用できます。 * 7.1.5.2 要素のイベントハンドラ、Documentオブジェクト、およびWindowオブジェクト — HTML 5.1 日本語訳 ``` Click me! (1) Click me! (2) ``` 「IE8- の `event` オブジェクトの参照不可」の制約の他にも「`onclick` イベントハンドラは2回以上代入すると上書きされてしまう」という問題があり、`atattchEvent`, `addEventListener` の併用が広く使われてきました。 ただし、`atattchEvent` は同じイベントタイプ、イベントハンドラ関数を指定する処理を2回以上行った場合、処理順がランダムになるという仕様がある為、「実行順を保証したい場合は1つの関数内で他の関数を呼び出すテクニック」が利用されてきました。 それでも、`atattchEvent` は2回イベント追加した場合に上書きされず、第1引数で `event` オブジェクトを利用可能だった為、`onclick` イベントハンドラよりは使い勝手が良かったといえます。 (蛇足) `atattchEvent` でも `addEventListener` と同等の機能を持つようにラップしたライブラリを過去に作りかけましたが、膨大な処理量だったのでメンテナンスを断念した覚えがあります。とはいえ、IE8- は今では Microsoft のサポート期間が切れているので特殊な事情がなければ考慮する必要はないでしょう。 * compatible-event.js : addEventListener, attachEvent のラッパー関数。addEvent したリスナーは window unload 時に削除される(循環参照対策)。attachEvent でも実行順が保証される。 Re: aaaaaaaa さん