attachEvent [JavaScript]
object.attachEvent(event, function)
これがなくちゃ JavaScript が始まらない、イベントハンドラの登録メソッド。
主要なブラウザの中では、Internet Explorer、Opera が対応しています。
Firefox、Safari、Google Chrome は対応していません(これらのブラウザは addEventListener メソッドを使います)。
組み込みクラスの中で、Object クラス、HTMLDocument クラス、Element クラスなどに準備されているメソッドで、イベントハンドラの登録に使います。
attachEvent で登録したイベントハンドラを開放するには、detachEvent メソッドを使います。
第一引数 event はイベント名文字列(プレフィックスに 'on' を含む)、第二引数 function は実行するイベントハンドラ メソッドです。
・・・・・・ところが。
問題は、イベントハンドラの実行順序なんです。
例えば、以下のようなソースを書いてみます(かなり乱暴なのはご勘弁を)。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>attachEvent</title>
<script type="text/javascript" >
//<![CDATA[
var strEventOrder = '';
function alertEventOrder(evt) {
alert(window.strEventOrder);
}
function resetEventOrder(evt) {
window.strEventOrder = '';
}
function addEventOrder(intOrder) {
if (window.strEventOrder != '') window.strEventOrder = window.strEventOrder + ', ';
window.strEventOrder = window.strEventOrder + String(intOrder);
}
//]]>
</script>
</head>
<body>
<input id="Button1" type="button" value="イベント発生" />
<input id="Button2" type="button" value="イベント順表示" />
<input id="Button3" type="button" value="イベント順リセット" />
</body>
<script type="text/javascript" >
//<![CDATA[
var elm = document.getElementById('Button1');
elm.attachEvent('onclick', function () { addEventOrder(1) });
elm.attachEvent('onclick', function () { addEventOrder(2) });
elm.attachEvent('onclick', function () { addEventOrder(3) });
elm.attachEvent('onclick', function () { addEventOrder(4) });
elm.attachEvent('onclick', function () { addEventOrder(5) });
elm.attachEvent('onclick', function () { addEventOrder(6) });
elm.attachEvent('onclick', function () { addEventOrder(7) });
elm.attachEvent('onclick', function () { addEventOrder(8) });
elm.attachEvent('onclick', function () { addEventOrder(9) });
elm.attachEvent('onclick', function () { addEventOrder(10) });
var elm = document.getElementById('Button2');
elm.attachEvent('onclick', function () { alertEventOrder() });
var elm = document.getElementById('Button3');
elm.attachEvent('onclick', function () { resetEventOrder() });
//]]>
</script>
</html>
やっていることは単純で、[イベント発生] ボタンで 10 回の addEventOrder 関数を呼び出し、[イベント順表示] ボタンでイベント発生順序を alert で表示します。
[イベント順リセット] で、イベント発生順序を記録する strEventOrder 文字列をクリアします。
Opera では、 [イベント発生] ボタン押下 → [イベント順表示] ボタン押下で、以下のように表示されます。
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
つまり、attachEvent で登録した順番を、きちんと守ってイベントハンドラが起動されています。
ところが、Internet Explorer では、こんな順番で表示されます(IE 8 で確認)。
9, 8, 7, 6, 10, 5, 4, 3, 2, 1
つまり、イベントハンドラが登録順に実行されるわけではなく、実行順序がめちゃくちゃなんですね。
バブルアップでもなければ、逆順でもありません。
どないやねん。
Internet Explorer で、attachEvent で登録したいイベントハンドラの実行順序を制御したい場合、組み込みクラス(Object、HTMLDocument、Element など)に実行順序を守るようなチェイン クラスを実装して吸収させるか、順番を守るひとつのイベントハンドラにまとめるか、手法が限られてきます。
あるいは、順番に左右されないイベントハンドラを設計するとかね(けっこう厄介だけど)。
この問題は、昔から Internet Explorer の JavaScript の障害のひとつなんですが、Internet Explorer 側での改善を待つより、プログラマ側で防衛策を取った方がよさそうです。
IEと firefox googlleは 違うんだ。
初めて知った。
by ゆうみ (2010-12-08 10:54)
そうなんですよ・・・・・・。
このせいで、製作者側はしっちゃかめっちゃかです;;;。
ほぼ、どんなブラウザでも動くようにしなきゃいけないですからねえ・・・・・・。
by みみちゃん (2010-12-08 23:35)