クロージャ(3)イベントフロー(3)概要mouseoverとmouseenterの違いコンテンツ作成においてマウスオーバーの処理はよく利用されます。jQueryではマウスオーバーに関連するイベントは2つ(mouseoverイベントとmouseenterイベント)あり初心者にとって分かりにくいので、ここで説明します。2つの違いはセレクタで指定した要素内に別の要素がある(入れ子構造の)時に生じます。マウスオーバーに関連する2つのイベント・mouseoverイベント→セレクタで指定した要素の子孫要素にも反応する・mouseenterイベント→セレクタで指定した要素にしか反応しないまた同じように要素からマウスが外れた時のイベントも2つあります。マウスアウトに関連する2つのイベント・mouseoutイベント→セレクタで指定した要素の子孫要素にも反応する・mouseleaveイベント→セレクタで指定した要素にしか反応しないほとんどの場合、セレクタで指定した要素にしか反応しないmouseenterイベントとmouseleaveイベントを利用すれば良いでしょう。mouseleaveメソッドです。onメソッドのイベント名の部分に設定してください。解説セレクタで指定した要素の子孫要素にも反応してしまう問題サンプル(flow3/01.html)のソースを開いてbody内にdiv要素が2つあることを確認してください。div要素は入れ子になっており、内側はid属性がin、外側はid属性がoutと設定されています。id="in"></div></div>jQueryは以下の様に記述されています。ポイントはセレクタに設定された「#out」です。このことを踏まえて、外側(id属性out)のdiv要素にマウスオーバーしてください。当たり前ですが、アラートで「mouseover」と表示されます。続いて内側(id属性がin)にマウスオーバーしてください。すると不思議なことに、ここでもアラートが表示されてしまいます。$("#out").mouseover(function(){alert("mouseover")});これは以前説明したイベントフローが関係しています。内側の要素で発生したイベントが親要素に伝わっていくため、内側のdiv要素から外側のdiv要素にイベントが伝わりアラートが表示されるのです。stopPropagationメソッドの利用を考えると思いますが、これは利用できません。これは受け取ったイベントを親の要素に伝えるのを停止しますが、子要素から送られてくるイベントの受け取り拒否はできないためです。上図に当てはめて考えます。内側の要素を緑のdiv、外側の要素を赤のdivと考えてください。stopPropagationメソッドを利用するとセレクタで指定した#outから親の要素にイベントが伝わるのを停止できます。上図では赤から青への伝達が停止されます。#inから#outに送られてくるイベントを停止することはできません。緑から赤への伝達は停止されません。これでは困るケースがあるので用意されているのがmouseenterイベントです。バブリングしないイベントこの問題に対応するためmouseoverイベントとは別にmouseenterイベントが用意されました。このイベントの特徴はバブリングしないことです。→参考:W3Cのmouseenterの説明で「Bubbles」の項目が「No」になっているのを確認してください。mouseenterメソッドを利用すると子要素(緑のdiv)にカーソルが重なっても、親の要素(赤いdiv)にイベントが渡らず、子要素(緑のdiv)にマウスカーソルが入ってもアラートが表示されないのです。サンプル(flow3/01b.html)のソースを開いて、以下の様にmouseenterメソッドに変更されている以外は、すべてflow3/01.htmlと同じ事を確認してください。$("#out").mouseenter(function(){alert("mouseenter")});結果として、内側(id属性in)のdiv要素にマウスオーバーしてもアラートは表示されなくなります。こちらの方が混乱しないと思うので、こちらを利用するようにしましょう。メモmouseoutイベントとmouseleaveイベントマウスアウトに関連するイベントも2つありますが、説明は同じなのでサンプルだけ紹介します。mouseoutメソッドのサンプル(flow3/02.html)を確認してください。外側のdiv要素から内側のdiv要素にマウスが移動した時にもアラートが表示されてしまいます。mouseleaveメソッドのサンプル(flow3/02b.html)では反応しません。外側のdiv要素(id属性out)から白いエリア(body要素)にでた時だけアラートが表示されます。hoverメソッドはmouseenterイベントとmouseleaveイベントを利用しています。サンプル(flow3/test01.html)のソースを開いて、body内の構成はflow3/01.htmlと同じ事を確認してください。hoverメソッドによってマウスが#outに入ったら「mouseenter」、#outからでたら「mouseleave」と表示するようにしています。leaveFunc);})サンプルでは内側のdiv要素(id属性はin)に反応しないことから、hoverメソッドがmouseenterイベントとmouseleaveイベントを利用している事が確認できます。これでイベントフローの説明は終わりです。次回は利用する画像データを前もって読み込むプリロードについて説明します。focus/blurとfocusin/focusoutmouseoverとmouseenterの関係(子孫要素に反応するか否か)と同じイベントが他にもあります。フォーカスした時に発生するイベントのfocusイベントとfocusinイベント、そしてフォーカスが外れた時に発生するイベントのblurイベントとfocusoutイベントです。フォーカスされた時のイベント・focusinイベント→セレクタで指定した要素の子孫要素にも反応する・focusイベント→セレクタで指定した要素にしか反応しないフォーカスが外れた時のイベント・focusoutイベント→セレクタで指定した要素の子孫要素にも反応する・blurイベント→セレクタで指定した要素にしか反応しないmouseenterイベントやmouseleaveイベントと同様にfocusイベントとblurイベントはバブリングしないため、子孫要素で発生したイベントには反応しません。マウスに関連するイベントと比較すると利用する機会も少ないと思いますが、合わせて覚えておくと良いでしょう。