【JavaScript】 event.stopPropagation() でドロップダウンメニューを作ろう。


HTML上にドロップダウンメニュー的なインターフェイスを作ろうとしたときに、メニューを出して消すのはいいが、メニュー上をクリックしてもすぐに消えちゃうという問題があって困った。

event.stopPropagation() というメソッドを使って、上手いこと解決できたので、実際に簡単なドロップダウンメニューを実装してみた。


この event.stopPropagation() については、下記のページで説明してくれている。

event.stopPropagation() がどういう働きをしているのかを理解するために、分解したサンプルを実装してみた。

まず改善されたコードが下記。(test1.htmlを参照)
やりたいことは、マウスダウンイベントでウィンドウを消すこと。サンプルコードでは、わかりやすいように、イベントの発生をアラートウィンドウで知らせるように書き換えてある。

<script type="text/javascript">
  $(document).ready( function(){
    $(document).mousedown(
      function(event){
        alert('Close panel');
      }
    );
    $('#panel').mousedown(
      function(event){
        event.stopPropagation();
        alert('Don\'t close panel!');
      }
    );
  } );
</script>
<div id="panel" style="background-color:#dddddd;">
  ここはドロップダウンメニュー!<br />
</div>

<div id="panel"> がドロップダウンメニューに当たると思って欲しい。
ドロップダウンメニュー上で mousedown すると "Don't close panel!"、それ以外のところでは "Close panel" のメッセージが表示される。これが正常な動作。

次に、ポイントとなるメソッド event.stopPropagation() が入っていないとどうなるか、実験してみる。(test2.htmlを参照)

<script type="text/javascript">
  $(document).ready( function(){
    $(document).mousedown(
      function(event){
        alert('mousedown! at document');
      }
    );
    $('#panel').mousedown(
      function(event){
        alert('mousedown! at panel');
      }
    );
  } );
</script>
<div id="panel" style="background-color:#dddddd;">
  ここはドロップダウンメニュー!<br />
</div>

このコードをテストすると、"Don't close panel!" が表示された直後に、"Close panel" が表示される。これでは、メニューを操作したくてマウスをダウンすると消えてしまう。

これは、マウスダウンのイベントが、子要素(div#panel)でも親要素(document)でも発生しており、子から親への順にイベント処理が進行(伝播=propagate)した結果の挙動。この伝播を止めるのが、event.stopPropagation() の仕事だということがわかる。


プロフィール

ときにはデザイナ、ときにはディレクタ、ときにはプログラマ、ときには何でも屋と、ウェブの世界で未熟ながらもいろいろやっている、コヤナギトモヤです。

ツイッター上ではこのヒト。
@tomk79

RSSフィード

ページの先頭へ戻る