Opera 9 はこのとおりの実装になっていますが、Firefox 2 および Safari 2 では window
オブジェクトがルートノードの役割を果たしています。すなわち、キャプチャリングフェーズは window
から始まり document
、ルート要素ノードと続いていき、逆にバブリングフェーズは window
で終わるのです。
DOM 2 Events では、addEventListener
メソッドで複数のイベントリスナが同じノード上に登録されたとき、それらをどういう順番で呼び出すかは規定されていません。しかし Firefox 2、Opera 9、Safari 2 はいずれも、登録されたのと同じ順番でイベントリスナを呼び出します。また、DOM 3 Events 草案でも、addEventListener
メソッドで登録されたイベントリスナは登録順で呼び出されることになっています。
DOM 2 Events では、あるノードがイベントを処理している間にそのノードに追加されたイベントリスナは、その処理中には呼び出されないことになっています。ただし、イベントフェーズが異なれば呼び出されるので、キャプチャリングフェーズ中に追加されたリスナなら、バブリングフェーズでは呼び出されます。また、あるノードがイベントを処理している間にそのノードから削除されたイベントリスナは、決してその処理中に呼び出されることはありません。
Firefox 2 および Safari 2 はこれを仕様どおり実装していますが、Opera 9 ではイベント処理中に現在のターゲットノードから削除されたイベントリスナも呼び出されてしまいます。
JavaScript では関数オブジェクトをそのままイベントリスナとして使えますが、これが呼び出されたときの関数内の this
が指す値は DOM 2 Events では規定されていません。Web Applications 1.0 には EventListener
インターフェースに関して In the ECMAScript binding itself, however, the
とありますが、これは handleEvent()
method of the interface is not directly accessible on Function
objects. Such functions, when invoked, must be called in the global scope.this
の値が window
オブジェクトになるということでしょうか?
実際には、Firefox 2、Opera 9、Safari 2 いずれも this
の値は現在イベントを処理中のノード、すなわち引数として渡されたイベントオブジェクトの currentTarget
プロパティの値と等しくなります。Firefox 2 ではテキストノード上のイベントリスナに関して、this
の値がイベントリスナ関数自身になってしまうバグがありますが、ナイトリービルドではすでに修正されています。また、Safari 2 では window
オブジェクト上のイベントリスナに渡されるイベントオブジェクトの currentTarget
プロパティの値が、キャプチャリングフェーズでは null
、バブリングフェーズでは document
オブジェクトになります。
余談ですが、上の引用をする際、Web Applications 1.0 の謝辞に Taken さんが載っていることに気づきました。一人だけ漢字なのでやたら目立ちますね。
イベントオブジェクトを作成するためには文書ノードの createEvent
メソッドを呼び出します。その際第 1 引数 eventType
に渡す文字列は、DOM 2 Events では "HTMLEvents"
、"UIEvents"
コメントをする