レイヤーの外にマウスを移動すると、子要素でイベント バブリングが発生します。
レイヤーベースのナビゲーションでは、レイヤーを閉じるために、マウスがレイヤーを離れるタイミングを知る必要がある場合があります。したがって、onmouseout イベント ハンドラーをレイヤーに登録します。ただし、イベント バブリングにより、マウスがレイヤー内の要素を離れたときにも、このイベント ハンドラーが起動します。
--------------
| Layer |.onmouseout = doSomething;
| -------- |
| | Link | ----> We want to know about this mouseout
| | | |
| -------- |
| -------- |
| | Link | |
| | ----> | but not about this one
| -------- |
--------------
---->: mouse movement
もう 1 つの問題は、マウスをレイヤーに移動してからリンクに移動すると、ブラウザーがレイヤーに mouseout イベントを登録することです。私にはあまり意味がありません (マウスはまだレイヤーにあります) が、すべてのブラウザーがこれに同意しています。
では、マウスが実際にレイヤーを離れたときに発生しないマウスアウトを拒否するにはどうすればよいでしょうか?
function doSomething(e) {
if (!e) var e = window.event;
var tg = (window.event) ? e.srcElement : e.target;
if (tg.nodeName != 'DIV') return;
var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
while (reltg != tg && reltg.nodeName != 'BODY')
reltg= reltg.parentNode
if (reltg== tg) return;
// Mouseout took place when mouse actually left layer
// Handle event
}
最初にイベントターゲットを取得します。マウスが移動した要素。ターゲットが DIV (レイヤー) でない場合は、マウスが確実にレイヤーを離れていないため、すぐに関数を終了します。
ターゲットがレイヤーの場合、マウスがレイヤーを離れたのか、レイヤー内のリンクに入ったのかはまだわかりません。したがって、イベントの relatedTarget/toElement をチェックします。マウスが移動した要素。
この要素を読み上げてから、イベントのターゲット (つまり DIV) または body 要素に遭遇するまで、DOM ツリーを上に移動します。
ターゲットに遭遇すると、マウスはレイヤーの子要素に向かって移動するため、マウスは実際にはレイヤーを離れていません。機能を停止します。
関数がこれらすべてのチェックに合格すると、マウスが実際にレイヤーを離れたことを確認し、適切なアクション (通常はレイヤーを非表示にする) を実行できます。
Mouseenter と mouseleave :
マイクロソフトには別の解決策があります。2 つの新しいイベント mouseenter と mouseleave が作成されました。イベントバブリングに反応しないことを除けば、mouseover や mouseout とほとんど同じです。そのため、登録されている HTML 要素全体を 1 つのソリッド ブロックとして認識し、ブロック内で発生するマウスオーバーや -out には反応しません。
したがって、これらのイベントを使用すると、問題も解決されます。これらのイベントは、登録されている要素でのマウスオーバー/アウトにのみ反応します。
現時点では、これらのイベントは Windows 上の Explorer 5.5 以降でのみサポートされています。他のブラウザー ベンダーがこれらのイベントをコピーする可能性があります。
イベントのバブリングが発生するため、mouseout ではなく mouseleave を使用することをお勧めします。