イベントリスナーの覚書
JavaScriptに実装されているイベントリスナーは、通常属性として、たとえばonclick="func()"と書くものをJavaScript側で処理してしまおうというもの。個人的にHTMLのコードがすっきりとしていて気に入っているのだが、IEだけ実装が違う。 Firefox、Opera、Safariなどのいわゆるモダンブラウザは、それぞれのHTMLオブジェクトにaddEventListener()というメソッドが実装されている。このメソッドは引数にイベント名, 関数, 実行フラグを必要とする。実行フラグは常にfalseを指定しておけば、イベントが発生した時に処理を実行してくれる。たとえば以下のように記述する。これはページがロードされたときに、message()という関数を実行させるという処理。気をつけなければならないのは、イベント名は、イベントハンドラ名のonを取り除いたものを指定し、関数名は()を記述してはいけない点だ。
IEではattachEvent()という関数でこれと同じ動きをする。引数にはイベント名, 関数を指定する。上記コードをIE用に書き換えると以下のようになる。
IEの場合は、イベント名はイベントハンドラ名をそのまま指定する。ここに注意だ。
さて、これを両方のブラウザに対応させた汎用的なコードにしたい。いろいろとやり方はあるだろうが、私は関数の実装を調べ、処理を分岐させる方法を使っている。
これはブラウザにattachEventが実装されているかを調べている。
ここまではいいのだが、問題この後だ。イベントが発生しているオブジェクトを拾うことができるが、これもIEだけ特殊な仕様になっている。
IEではeventオブジェクトにこれらの情報を持つようになっていて、イベントが発生したオブジェクトはevent.srcElementで参照できる。一方他のモダンブラウザでは、イベント時に実行する関数の引数にevtという変数を設定し、これがオブジェクトへの参照になっている。よって上記コードでもその処理がされているわけだが、非常に面倒くさいものである。
イベント時に実行する関数に引数を渡したい場合は、以下のように無名関数をかます必要がある。
この引数にオブジェクトへの参照を渡したい場合もあるだろう。つまり、this参照を使って自分自身の持っているプロパティにアクセスしたい場合だ。この場合addEventListenerを実装するブラウザではthis参照を使用できるがattachEvent、つまりIEではthis参照が使えないということがある。これの回避方法だが、event.srcElementを指定することで可能のようだ。以下に、フォームのボタンを例にとった場合を示す(JavaScriptだけの記述とする)。