SSブログ

detachEvent [JavaScript]

object.detachEvent メソッド

object.detachEvent(event, function)

attachEvent で登録したイベントハンドラを開放するのが、detachEvent の役割です。

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

FirefoxSafariGoogle Chrome は対応していません(これらのブラウザは removeEventListener メソッドを使います)。

組み込みクラスの中で、Object クラス、HTMLDocument クラス、Element クラスなどに準備されているメソッドです。

第一引数 event はイベント名文字列(プレフィックスに 'on' を含む)、第二引数 function は登録されているイベントハンドラ メソッドです。

attachEventdetachEvent を使うと、<body onload="hoge();"> なんていう恰好悪い書き方をしなくても、 window のロードを検知して JavaScript を起動する処理を、スマートに書くことができます。

・・・・・・なお。

detachEvent でも、解放できないイベントハンドラがあるので、注意が必要です。

【注意】:匿名関数イベントハンドラの開放について、追記があります。

こんなソースを書いてみました。

<!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>detachEvent</title>
    <script type="text/javascript" >
        //<![CDATA[

        // input text にメッセージ出力
        function outputMessage(strMessage) {
            var elm;
            elm = document.getElementById('Text1');
            elm.innerText = strMessage;
        }

        // [attachEvent イベントハンドラ] ボタンのイベントハンドラ
        function onClickButton1(evt) {
            var elm = document.getElementById('Button1');
            elm.detachEvent('onclick', onClickButton1);
            outputMessage('attachEvent イベントハンドラをデタッチしました。');
        }

        // [匿名関数イベントハンドラ] ボタンのイベントハンドラ
        function onClickButton2(evt) {
            var elm = document.getElementById('Button2');
            elm.detachEvent('onclick', function () { onClickButton2(); });
            outputMessage('匿名関数イベントハンドラはデタッチできません。');
        }

        // [HTML の onclick イベントハンドラ] ボタンのイベントハンドラ
        function onClickButton3(evt) {
            var elm = document.getElementById('Button3');
            elm.detachEvent('onclick', onClickButton3);
            outputMessage('HTML の onclick イベントハンドラはデタッチできません。');
        }

        // [テキストボックスのリセット] ボタンのイベントハンドラ
        function onClickButton4(evt) {
            outputMessage('');
        }

        // ウィンドウ ロード イベントハンドラ
        function onWindowLoad(evt) {
            window.detachEvent('onload', onWindowLoad);
            var elm;
            elm = document.getElementById('Button1');
            elm.attachEvent('onclick', onClickButton1);
            elm = document.getElementById('Button2');
            elm.attachEvent('onclick', function () { onClickButton2(); });
            outputMessage('Window のロードが完了しました。');
        }

        // ウィンドウ ロード イベントハンドラの登録
        window.attachEvent('onload', onWindowLoad);

        //]]>
    </script>
</head>
<body>
    <input id="Text1" type="text" style="width: 50%;" readonly="readonly" value="Window のロード中です。" />
    <br />
    <input id="Button1" type="button" value="attachEvent イベントハンドラ" />
    <br />
    <input id="Button2" type="button" value="匿名関数イベントハンドラ" />
    <br />
    <input id="Button3" type="button" value="HTML の onclick イベントハンドラ" onclick="onClickButton3();" />
    <br />
    <input id="Button4" type="button" value="テキストボックスのリセット" onclick="onClickButton4();" />
    <br />
</body>
</html>

JavaScript の中で、window オブジェクトに対して onload イベントに onWindowLoad イベントハンドラを登録していますが、これが <body onload="hoge();"> の代わりに、window オブジェクトのロードイベントをひっかけて、JavaScript を起動する仕組みです。

window オブジェクトのロードイベントをハンドルするイベントハンドラでは、きちんと detachEvent で自分自身を開放しておきましょう。

このサンプル ソースでは、他に 3 通りの detachEvent を試しています。

ひとつめは、きちんと定義された(つまり、匿名関数ではない)関数を attachEvent したものに対して、detachEvent する例。

このケースは、attachEvent されたイベントハンドラが、detachEvent できちんと解放されます。

ふたつめは、attachEvent でイベントハンドラとして匿名関数が登録された例。

このケースでは、attachEvent で登録したイベントハンドラであっても、detachEvent で開放することはできません。→すみません、ウソでした。【追記】を参照してください。

みっつめは、HTML onclick 属性で指定したイベントハンドラに対して、detachEvent を試みる例。

このケースでも、 イベントハンドラを detachEvent で開放することはできません。

これらの挙動は、Internet Explorer でも Opera でも同じです。

まあ、よっぽどの事情がない限り attachEvent で無名関数をイベントハンドラに登録することもないでしょうし、個人的には HTML onclick 属性を使うのも好きではないので、あんまり問題はないんですが。

一応、「そういう挙動をするんだよ」という、備忘録代わりに記しておきます。

【追記】:2010/12/09 0:42

匿名関数イベントハンドラを開放する方法を発見しました。

        // ウィンドウ ロード イベントハンドラ
        function onWindowLoad(evt) {
            window.detachEvent('onload', onWindowLoad);
            var elm;
            elm = document.getElementById('Button1');
            elm.attachEvent('onclick', onClickButton1);
            elm = document.getElementById('Button2');
            elm.attachEvent('onclick', function () { onClickButton2(); elm.detachEvent('onclick', arguments.callee); });
            outputMessage('Window のロードが完了しました。');
        }

arguments.callee がキーです。

こいつは、呼び出された関数内で、その関数への参照を保持しているようです。

そのおかげで、無名関数でも、(その関数内であれば)関数を操作できるんですね。

Internet Explorer でも、Opera でも動作を確認しました。

これを attachEvent で呼び出されるイベントハンドラ側に渡してやれば、少しは構造的な仕組みで無名関数を detachEvent で開放できるかもしれませんね。

一応、テクニックとして残しておきます。


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

nice! 3

コメント 4

ゆうみ

まったくわからない。
横文字が てんこ盛り並んでる。
by ゆうみ (2010-12-09 11:26) 

みみちゃん

これでお給料頂いてます、はいw。
by みみちゃん (2010-12-09 19:37) 

One-for-you

これも語学ですよねw 
フローを書いて(または場当たり仕様)、それをlanguageに展開できるようになりたい、と思ってます
by One-for-you (2010-12-10 01:46) 

みみちゃん

語学ですね。
俺の哲学は「日本語が喋れるならプログラムを書ける」です。
by みみちゃん (2010-12-10 20:47) 

コメントを書く

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

トラックバック 3

attachEventaddEventListener ブログトップ

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