phi

I'm a Game Programmer and Frontend Engineer passionate about programming education. Math / C / C++ / C# / JavaScript / HTML5 / CSS3 / Python

phiaryjust a creator

JavaScript Tips – dispatchEvent を使いこなそう!!

13 years ago

JavaScript の dispatchEvent の情報があまりにも少なかったので解説用にサンプルを作ってまとめてみました. このエントリーでは dispatchEvent の基本的な使い方と活用例について解説します.

うまく使えばネイティブっぽく JavaScript を拡張したりってこともできる便利な関数です.

About

今回制作したサンプルデモは2つ.

最初のサンプルはイベントを発行するサンプルです. boxB をクリックした際に boxA のクリックイベントも発生するようになっています.

2つ目のサンプルは rightclick イベント という 右クリックしたときのみ発行する独自イベントを定義しています.

Code

今回制作したサンプルデモ1個目の全体コードです.

<!DOCTYPE html>

<html>

    <head>
        <meta charset="UTF-8">

        <link rel="stylesheet" type="text/css" href="style.css" />
        <script>

            window.onload = function() {

                var eBoxA = document.getElementById("boxA");    // boxA 要素取得
                var eBoxB = document.getElementById("boxB");    // boxB 要素取得

                // boxA にクリックイベントを登録
                eBoxA.addEventListener("click", function(e){
                    log("boxA");
                }, false);

                // boxB にクリックイベントを登録
                eBoxB.addEventListener("click", function(e){
                    log("boxB");

                    // eBoxA のクリックイベントをディスパッチ起動
                    var evt = document.createEvent("MouseEvents");
                    evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                    eBoxA.dispatchEvent( evt );

                    // webkit 系だと下記でも ok 
                    //eBoxA.dispatchEvent(new Event("click"));
                }, false);
            };

            var log = function(str) {
                console.log(str);

                var eConsole = document.getElementById("console");
                eConsole.innerHTML += str;
                eConsole.innerHTML += "\n";
            };

        </script>
    </head>

    <body>
        <header>
            <h1>JavaScript Tips - dispatchEvent を使いこなそう!! - 任意のタイミングでイベントを発行しよう</h1>
            <p>
                boxB をクリックした際に boxA のクリックイベントも発生するようにしてみました.
            </p>
            <p>
                boxA をクリックした際は "boxA" としか表示されませんが, boxB をクリックすると "boxB", "boxA" と表示されるのがわかるかと思います.
            </p>
        </header>

        <section>
            <h2>main</h2>
            <div id="main">
                <div id="boxA" class="box">boxA</div>
                <div id="boxB" class="box">boxB</div>
            </div>
        </section>

        <section>
            <h2>Console</h2>
            <pre id="console"></pre>
            <button onclick="document.getElementById('console').innerHTML = '';">Clear</button>
        </section>

        <footer>
            <h2>Links</h2>
            <a href="index.html">トップ</a>
        </footer>
    </body>

</html>  

Tips

dispatchEvent とは

Flash で AS を触った経験のある方にとってはお馴染みかもしれませんが, dispatchEvent とは名前の通りイベントをディスパッチ(発行)する関数です. これを使えば, A をクリックしたときに一緒に B のクリックイベントを起動したり, 独自のイベントを定義したりってことが可能になります.

主な用途はこちら

  • 任意のタイミングでイベントを発行
  • 独自イベントを定義

dispatchEvent の使い方

dispatchEvent は取得した dom 要素に対して実行します. 引数はイベントオブジェクトです.

例) クリックイベントをディスパッチ

var evt = document.createEvent("MouseEvents");  
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, elm);  
elm.dispatchEvent( evt );  

これを実行すると elm をクリックしていなくてもクリックイベントが実行されます.

event オブジェクトの初期化方法

event オブジェクトは createEvent で生成したいオブジェクト名を指定し, 生成したオブジェクトに応じた初期化メソッドで初期化します.

上のサンプルでは引数を 15個も渡して initMouseEvent というメソッドが初期化メソッドです. この仕様がおそらく Flash よりも dispatchEvent の普及を遅らせている要因の一つではないかなと思います.

今回のサンプルでは MouseEvent を生成していますが, ほかにも UIEvent だとか KeyboardEvent などもあり, それぞれたくさんの引数を受け取る初期化メソッドがあります.

全て解説していると日が暮れるので今回は MouseEvent の初期化 initMouseEvent の引数についてだけ解説します.

MouseEvent の引数名はこんな感じです.

event.initMouseEvent(type, canBubble, cancelable, view,  
                     detail, screenX, screenY, clientX, clientY, 
                     ctrlKey, altKey, shiftKey, metaKey, 
                     button, relatedTarget);

type ... セットするマウスイベントのタイプです. 設定可能なタイプは click, mosuedown, mouseup, mouseover, mousemove, mouseout です.

  • canBubble ... バブリング可能か. event.bubbles の値を設定します.
  • cancelable ... イベントのデフォルト処理を制御可能か. event.cancelable の値を設定します.
  • view ... イベントのAbstractView(抽象的なビュー?). よく意味がわかりませんが, とりあえず window を設定しておけば問題ありません.
  • detail ... マウスクリックの回数
  • screenX ... イベントの画面のX座標. evnet.screenX の値を設定します.
  • screenY ... イベントの画面のY座標. evnet.screenY の値を設定します.
  • clientX ... イベントのクライアントのX座標. evnet.clientX の値を設定します.
  • clientY ... イベントのクライアントのY座標. evnet.clientY の値を設定します.
  • ctrlKey ... イベント中に Ctrl キーを押した状態にするかどうか. bool 値.
  • altKey ... イベント中に Alt キーを押した状態にするかどうか. bool 値.
  • shiftKey ... イベント中に Shift キーを押した状態にするかどうか. bool 値.
  • metaKey ... イベント中に Meta キーを押した状態にするかどうか. bool 値.
  • button ... マウスボタンの状態. event.button の値を設定します. 通常のマウスイベントと同様 0:左クリック, 1:中央クリック, 2:右クリックです.
  • relatedTarget ... イベントに関連するイベントターゲットです. mouseover ã‚„ mouseout で使用します. 他のケースでは null を渡します.

他のイベントについてはこちらを参考にしてください.

Reference

次回は dispatchEvent を使ってテキストエリアの値の変更をリアルタイムで検知するイベントを定義しようと思います.