ホームページ >ウェブフロントエンド >jsチュートリアル >javascript_javascript スキルでのマウスオーバーとマウスアウトの使用方法の詳細な説明
この記事では、event 要素の子要素のバブリングを実際に防ぐことはできません...
子要素がイベント要素にバブルするときに、イベントをトリガーするかどうかを判断するだけです。ああ...いいえ、イベント関数で関連する操作を実行するかどうかを判断する必要があります...
まず、ここをクリックしてください: 問題の発生
注: jquery のマウスオーバー/アウト イベントにもこの問題があります
解決策 1:
IEでは、mouseoverとmouseoutを置き換えるmouseenterイベントとmouseleaveイベントがあります。
インターネット上では、これら 2 つのイベントは IE のみでサポートされており、他のブラウザではサポートされていないという意見が多数あります。
しかし、Firefox と Google の最新バージョンは、mouseenter と Mouseleave をサポートしています。 ! ! ! !
さらに、IE のサポート範囲は [ie5] なので、IE をスプレーしないでください...
他のブラウザでテスト済み:
Mouseenter と Mouseleave は Firefox/3.6.28 ではサポートされていません。Firefox のどのバージョンがこれら 2 つのイベントをサポートするかは不明です...
Opera9.50 Alpha および Opera9.00 Beta ではサポートされていません。実際、Opera を今すぐテストする必要はありません。Opera の最新バージョンは Webkit カーネルに基づいています...
Google の下位バージョンはテストされていません...
もちろん、これらの古いバージョンのブラウザは基本的に無視できるため、これが最良の解決策となるはずです。mouseover と Mouseout を置き換えるために、mouseenter と Mouseleave イベントを使用します。
これら 2 つのイベントの例については、ここをクリックしてください:mouseenter と Mouseleave
注: jquery には、すべてのブラウザーと互換性のある Mouseenter イベントと MouseLeave イベントもあります。
解決策 2:
上記の方法は、古いバージョンの Firefox および Google ではサポートされていません。最大限の互換性が必要な場合は、以下を読み続けてください。
イベント関連の要素を取得するには、var reltg = e.popularTarget ? e.popularTarget : e.type == 'mouseout' ? e.toElement : e.fromElement を使用します。次に、このイベント関連要素とイベント要素の間の関係 (包含関係) を使用して、関連するイベント処理を実行するかどうかを決定します。
mouseout イベントの場合、reltg はマウス ポインタがターゲットから離れるときに入るノードです。
mouseover イベントの場合、reltg はマウス ポインタがターゲット ノードに移動するときに離れるノードです。
li の Mouseout イベント関数では、reltg が li の子要素である場合、関連する操作を実行する必要はありません。reltg が li の親要素である場合、関連する操作を実行します。
li と reltg の包含関係は、次の isMouseLeaveOrEnter 関数によって判断できます。
//判断事件相关元素与li的关系 如果事件相关元素为li的子元素就返回false 反之返回true function isMouseLeaveOrEnter(e, handler) { if (e.type != 'mouseout' && e.type != 'mouseover') return false; var reltg = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement; while (reltg && reltg != handler) reltg = reltg.parentNode; return (reltg != handler); }; Li.onmouseout = function(e) { e = e||window.event; if (isMouseLeaveOrEnter(e,this)) { //运行相关操作 }; }
このメソッドの明らかな欠点は、isMouseLeaveOrEnter ですべての親要素をトラバースする必要があることです。これはパフォーマンスの問題です
解決策 3:
このメソッドの考え方はメソッド 2 と同じですが、compareDocumentPosition/contains を使用して li と reltg の間の包含関係を決定する点が異なります。これにより、メソッド 2 ですべての親要素を走査することによって発生するパフォーマンスの問題が最適化されます。
コードを直接見てみましょう:
//判断node是否为parent的子元素 //if node == parent 也会返回true function contains(parent, node) { if(parent.compareDocumentPosition){ //ff var _flag = parent.compareDocumentPosition(node); return (_flag == 20 || _flag == 0)? true : false; }else if(parent.contains){ //ie return parent.contains(node); } }; Li.onmouseout = function(e) { e = e||window.event; var relatedEle = e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement if (!contains(this, relatedEle)) { show.innerHTML=show.innerHTML+'0'; } }
compareDocumentPosition() メソッドは 2 つのノードを比較し、ドキュメント内のそれらの位置を表す整数を返します。
戻り値は次のとおりです:
1: 関係ありません。2 つのノードは同じドキュメントに属しません。
2: 最初のノード (P1) は 2 番目のノード (P2) の後ろに位置します。
4: 最初のノード (P1) が 2 番目のノード (P2) の前に位置します。
8: 最初のノード (P1) は 2 番目のノード (P2) 内に位置します。
16: 第 2 ノード (P2) は第 1 ノード (P1) 内に位置します。
32: 関係がないか、2 つのノードは同じ要素の 2 つの属性です。
注: 戻り値は値の組み合わせにすることができます。たとえば、20 が返されるということは、p2 が p1 (16) の内側にあり、p1 が p2 (4) の前にあることを意味します。
[ie8 は、compareDocumentPosition() メソッドをサポートしていません。代わりに、compareDocumentPosition() メソッドを使用して、nodeB が別のノード A に含まれているかどうかを判断します。 )
以上がこの記事の全内容です。皆さんに気に入っていただければ幸いです。