WEBサービス創造記

WEBサービスを作ったり保守したりしてる人のメモブログです。

JavaScriptのイベント伝播について覚書

      2012/12/18

JavaScriptのイベント伝播について

掲題の通り、JavaScriptのイベント伝播(でんぱ)について知る機会があったのでその覚書です。

きっかけは、preventDefault()というメソッド。jQuery系のライブラリなどでたまに見かけてたんですが、どんなメソッドか知らなかったので調べてみることにしました。
調べてみた結果、

イベントがキャンセル可能である場合、イベントのさらなる伝播 (propagation) を止めずに、そのイベントをキャンセルします。

とありました。
これを見たときに「え、return false;と何が違うの?」と思ったんですが、その時点でJavaScriptのイベント伝播について理解していなかったようです。

JavaScriptではHTMLをDOMとしてパースし、任意のノードを特定して操作することができます。
例えば、下図のようなDOMがあるとします。

a要素がクリックされたときは、子要素から順にDOMをたどって、一番上のノードであるwindowまで伝わります。これがイベントの伝播です。

例えば、よく使われるクリックイベントなんかを例にしてみると、自分がクリックされなくても子要素がクリックされたら発生するようになっています。
a要素がクリックされたらその親要素であるp要素より上の要素すべてでクリックイベントが伝播していき、p要素がクリックされた場合はその親要素であるdiv要素より上に順に伝播していくわけです。

この現象は、イベントの伝播以外にもイベントのバブリングなどとも呼ばれているようです(バブルは泡の意。泡が浮き上がってくるようにイベントが伝播する様子かららしい)。

イベント伝播の制御

以下の3つのメソッドでイベント伝播を制御することができます。

  • return false;
  • e.preventDefault();
  • e.stopPropagation();

return false;

これはよく使うと思います。
これは実行した要素で全てを止めてしまいたいときに使います。return false;した場合は親要素へのイベント伝播はストップします。

e.preventDefault();

既出の引用の通りです。

イベントがキャンセル可能である場合、イベントのさらなる伝播 (propagation) を止めずに、そのイベントをキャンセルします。

当該要素でのイベントはキャンセルしますが、親要素へのイベント伝播を止めたくないときに使います。
なお、イベントキャンセルが可能である場合というのがポイントです。

イベントがキャンセル可能かどうかは event.cancelable を使って確認できます。キャンセル不可能なイベントに対して preventDefault を呼び出しても効果はありません。

e.stopPropagation();

当該要素のイベントは活かしつつも、親要素へのイベント伝播は止めたいときに使います。

まとめ

まとめると下表の通りになります。

return false; 当該要素でイベントをキャンセルし、親要素へのイベント伝播も止める。
e.preventDefault(); 当該要素でイベントをキャンセルするが、親要素へのイベント伝播は止めない。
e.stopPropagation(); 当該要素のイベントはキャンセルしないが、親要素のイベント伝播は止める。

 - JavaScript