SSブログ

attachEvent [JavaScript]

object.attachEvent メソッド
object.attachEvent(event, function)

これがなくちゃ JavaScript が始まらない、イベントハンドラの登録メソッド。

主要なブラウザの中では、Internet ExplorerOpera が対応しています。

FirefoxSafariGoogle 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 で登録したいイベントハンドラの実行順序を制御したい場合、組み込みクラス(ObjectHTMLDocumentElement など)に実行順序を守るようなチェイン クラスを実装して吸収させるか、順番を守るひとつのイベントハンドラにまとめるか、手法が限られてきます。

あるいは、順番に左右されないイベントハンドラを設計するとかね(けっこう厄介だけど)。

この問題は、昔から Internet Explorer JavaScript の障害のひとつなんですが、Internet Explorer 側での改善を待つより、プログラマ側で防衛策を取った方がよさそうです。


nice!(2)  コメント(2)  トラックバック(3) 
共通テーマ:パソコン・インターネット

nice! 2

コメント 2

ゆうみ

IEと firefox googlleは 違うんだ。
初めて知った。
by ゆうみ (2010-12-08 10:54) 

みみちゃん

そうなんですよ・・・・・・。
このせいで、製作者側はしっちゃかめっちゃかです;;;。
ほぼ、どんなブラウザでも動くようにしなきゃいけないですからねえ・・・・・・。
by みみちゃん (2010-12-08 23:35) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 3

統合インデックスdetachEvent ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。