質問するログイン新規登録

回答編集履歴

2

attachEvent, HTML要素のイベントハンドラの説明追記

2016/04/13 04:33

投稿

think49
think49

スコア18194

answer CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  - イベントタイプ (`type`)
14
14
  - コールバック関数 (`callback`)
15
- - キャプチャリングフェーズ使用するかの真偽値 (`capture`)
15
+ - キャプチャリングフェーズ使用するかの真偽値 (`capture`)
16
16
  - デフォルトアクションをキャンセルするかの真偽値(`passive`)
17
17
  - イベントリスナを削除するかの真偽値(`removed`)
18
18
 
@@ -20,7 +20,9 @@
20
20
 
21
21
  ### イベントハンドラ(event handler)
22
22
 
23
+ **addEventListener のイベントハンドラ**
24
+
23
- `addEventListener` において第2引数に指定可能なオブジェクトです。
25
+ `addEventListener` において第2引数に指定可能なオブジェクト(EventListener インターフェースを実装するオブジェクト)です。
24
26
  UI Events では「EventListener インタフェースを実装する利用者オブジェクトであって `handleEvent()` コールバックメソッドを提供するもの」としていますが、その後で「注記: JavaScript においては、利用者定義の関数は, EventListener インタフェースを実装するものと見なされる。 したがって、その関数の呼び出し時には,その最初の引数にイベントオブジェクトが渡されることになる。 加えて、 JavaScript オブジェクトは, handleEvent メソッドを定義して EventListener インタフェースを実装することもできる。」ともある為、`handleEvent()` を持たなくてもイベントハンドラと呼称できます。
25
27
 
26
28
  - [イベントハンドラ ( event handler )- UI Events (日本語訳)](http://www.hcn.zaq.ne.jp/___/WEB/uievents-ja.html#event-handler)
@@ -34,4 +36,64 @@
34
36
  element.addEventListener('click', {handleEvent: handleClick}, false); // {handleEvent: handleClick} がイベントハンドラ
35
37
  ```
36
38
 
39
+ **atattchEvent のイベントハンドラ**
40
+
41
+ IE8- 全盛期時代では IE8- が `addEventListener` をサポートしなかった為、`attachEvent` を併用して実装されました。
42
+ MSDN では `attachEvent` の第2引数を `pDisp` であり、`pDisp`を「イベントハンドラが呼び出されるより前に呼び出される関数」と定義しています。
43
+ .NET Framework では `attachEvent` の第2引数を `System.EventHandler` 型の `handler` としており、「イベントハンドラ関数」と呼称しても概ね問題ないと思います。
44
+
45
+ - [attachEvent method (Internet Explorer)](https://msdn.microsoft.com/en-us/library/ms536343.aspx)
46
+ - [HtmlObject.AttachEvent メソッド (String, EventHandler) (System.Windows.Browser)](https://msdn.microsoft.com/ja-jp/library/cc190195.aspx)
47
+
48
+ ```JavaScript
49
+ fuction handleClick (event) {
50
+ console.log(event.type);
51
+ }
52
+
53
+ if (element.addEventListener) {
54
+ element.addEventListener('click', handleClick, false); // handleClick がイベントハンドラ
55
+ } else if (element.attachEvent) {
56
+ element.attachEvent('onclick', handleClick); // handleClick がイベントハンドラ
57
+ }
58
+ ```
59
+
60
+ **HTML 要素のイベントハンドラ**
61
+
62
+ 更に古くは要素自身が持つ `onclick` イベントハンドラ等を利用して実装されました。
63
+ これは長らく標準化されてきませんでしたが、HTML5 (HTML Living Standard)で標準化され、今でも使用できます。
64
+
65
+ - [7.1.5.2 要素のイベントハンドラ、Documentオブジェクト、およびWindowオブジェクト — HTML 5.1 日本語訳](http://momdo.github.io/html51/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects)
66
+
67
+ ```HTML
68
+ <p id="sample">Click me! (1)</p>
69
+
70
+ <script>
71
+ 'use strict';
72
+ function handleClick1 (evt) { // IE8- では JavaScript の onclick プロパティを使用して呼び出された関数の第一引数で event オブジェクトを参照できない制約があります
73
+ evt = evt ? evt : window.event; // IE8- の独自拡張 window.event を利用し、IE8- でも event オブジェクトを参照出来るようにします
74
+ console.log(evt.type);
75
+ }
76
+
77
+ function handleClick2 (event) { // HTML の onclick 属性内で event オブジェクトを渡している為、IE8- でも event オブジェクトを参照できます
78
+ console.log(event.type);
79
+ }
80
+
81
+ document.getElementById('sample').onclick = handleClick1;
82
+ </script>
83
+
84
+ <!--
85
+ HTMLのonclick属性内の JavaScript コードでは IE8- も含めて event オブジェクトを参照できます。
86
+ この event オブジェクトは window.event と等価ではありません。
87
+ -->
88
+ <p onclick="handleClick2(event);">Click me! (2)</p>
89
+ ```
90
+
91
+ 「IE8- の `event` オブジェクトの参照不可」の制約の他にも「`onclick` イベントハンドラは2回以上代入すると上書きされてしまう」という問題があり、`atattchEvent`, `addEventListener` の併用が広く使われてきました。
92
+ ただし、`atattchEvent` は同じイベントタイプ、イベントハンドラ関数を指定する処理を2回以上行った場合、処理順がランダムになるという仕様がある為、「実行順を保証したい場合は1つの関数内で他の関数を呼び出すテクニック」が利用されてきました。
93
+ それでも、`atattchEvent` は2回イベント追加した場合に上書きされず、第1引数で `event` オブジェクトを利用可能だった為、`onclick` イベントハンドラよりは使い勝手が良かったといえます。
94
+
95
+ (蛇足) `atattchEvent` でも `addEventListener` と同等の機能を持つようにラップしたライブラリを過去に作りかけましたが、膨大な処理量だったのでメンテナンスを断念した覚えがあります。とはいえ、IE8- は今では Microsoft のサポート期間が切れているので特殊な事情がなければ考慮する必要はないでしょう。
96
+
97
+ - [compatible-event.js : addEventListener, attachEvent のラッパー関数。addEvent したリスナーは window unload 時に削除される(循環参照対策)。attachEvent でも実行順が保証される。](https://gist.github.com/think49/882821)
98
+
37
99
  Re: aaaaaaaa さん

1

誤字修正

2016/04/13 04:33

投稿

think49
think49

スコア18194

answer CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  ### イベントリスナ(event listener)
10
10
 
11
- [DOM Standard(日本語訳)](http://www.hcn.zaq.ne.jp/___/WEB/DOM4-ja.html#concept-event-listener) ではのフィールドからなるものを「イベントリスナ」としています。
11
+ [DOM Standard(日本語訳)](http://www.hcn.zaq.ne.jp/___/WEB/DOM4-ja.html#concept-event-listener) では下記のフィールドからなるものを「イベントリスナ」としています。
12
12
 
13
13
  - イベントタイプ (`type`)
14
14
  - コールバック関数 (`callback`)