【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() の仕事だということがわかる。


プロフィール

コヤナギ トモヤ

ウェブ系エンジニアしてます。ウェブデザイナー、ウェブディレクターとしてウェブ制作の仕事に携わり、今はエンジニア職に流れ着きました。誰かのお仕事をちょっとだけ効率化するような支援ツールの開発が好き。オープンソースとMITライセンス大好き。人生後半は自由と民主主義のコントリビューターとして過ごす予定。

ウェブ制作支援ツール Pickles 2 をオープンソースで開発しています。

PHP/JavaScript/NodeJS/nwjs/Laravel/Pickles2/オープンソース/心理学/倫理/自由と民主主義

RSSフィード

ページの先頭へ戻る