初心者向けのjQuery入門講座|デザイナー向けのJavaScriptライブラリ

このエントリーをはてなブックマークに追加
索引
1章:jQuery入門
2章:jQuery基礎
3章:jQuery発展
番外編:研究

イベントフロー(1)

イベントは伝播する

イベントは発生した要素だけでなく、他の要素にも伝播する場合があります。このことを理解していないと思わぬ動作に戸惑うことになりますので、ここで学んでおきましょう。まずはサンプル(02/11_01.html)でイベントの伝わり方(イベントフロー)を確認しましょう。

まずはbody内の構造を確認して下さい。3つのdivが入れ子になっています(青の中に赤、赤の中に緑)。つづいてjQueryを見て下さい。以下の様にdivがクリックされたら、そのidをalertで表示するようになっています。サンプルではdivにblue,red,greenと付けられているので、それらの名前が表示されるはずです。

$("div").click(function () {
	alert(this.id);
})

jQueryを確認したら緑のdiv領域をクリックしてください。緑のdivのidであるgreenがアラートで表示されるのは分かるのですが、redやblueまでアラートで表示されます。

これはclickだけでなくonのイベントハンドラを利用したときも同じです。サンプル(02/11_02.html)で緑のdiv領域をクリックして同じように3回アラートが表示されるのを確認して下さい。onはlive/delegateの構文で書きました。要素数が少ないので調査範囲はdocumentにしてあります。

深いタグ階層から浅いタグ階層へ

クリックしたのはgreenのdiv領域だけなのに、なぜ他のdivもアラートが表示されるのでしょうか? 理解のポイントはdivの入れ子構造です。左図のようにイメージしてください。greenのdiv領域はredやblueの内部にあるため、その背後にはredやblueのdiv領域が存在しているのです。そしてクリックすると、矢印のようにイベントは奥のdiv領域にも伝わっていくのです。greenのdiv領域はredのdiv領域内にあります。ですからgreenのdiv領域もredのdiv領域になるため、redがクリックに反応するのも自然なのです。階層で説明するとイベントは深いタグ階層から浅いタグ階層に伝わるとなります。

緑だけアラート表示したい

ではgreenのdiv領域だけアラートを表示したい場合はどうするのか?対応はシンプルです。セレクタでidをgreenに限定すればよいのです。サンプル(02/11_03.html)で確認して下さい。jQueryではonのイベントハンドラを利用し、セレクタにidがgreenのdivを設定しました。

$(document).on("click", "div#green", function () {
	alert(this.id);
})

ちなみに以下の様に調査範囲をdiv、セレクタを#greenとしたサンプル(02/11_04.html)ではgreenのdiv領域をクリックすると2回アラートが表示されます。何故かというとgreenは2つのdiv(idはred,blue)に囲まれているため2回調査されてしまうためです。通常はdivという点在する要素を調査範囲に設定することはありません、デリゲートとonで説明したように特定の1領域を指定するようにします。

$("div").on("click", "#green", function () {
	alert(this.id);
})

入れ子のdivに効率よくイベントを設定したい

しかし緑だけでなく、赤や青のdiv領域をクリックしたときもアラートを表示したいときは、どうすればよいのでしょうか?安直な方法としてはサンプル(02/11_05.html)のように3つのid毎にセレクタを設定することが考えられます。しかし緑のdiv領域をクリックすると、blueやredのアラートも表示されてしまいます。これはgreenをクリックしてもイベントが緑の背後にあるredやblueにも伝播するため反応してしまうのです。次回はこの問題に対処する方法を説明します。

$(document).on("click", "div#blue", function () {
	alert(this.id);
})
$(document).on("click", "div#red", function () {
	alert(this.id);
})
$(document).on("click", "div#green", function () {
	alert(this.id);
})

ちなみにセレクタの設定は,(カンマ)を利用するとor指定ができるのでサンプル(02/11_06.html)のように1つのonにまとめることができます。リファレンス:セレクタ(or)セレクタ(and)

$(document).on("click", "div#green, div#red, div#blue", function () {
	alert(this.id);
})