問題の説明
マウスがID1に移動すると、ID2が表示され、マウスがID1を離れるとID2が表示されることを願っています。質問は次のとおりです。
1.マウスがID1からID2に移動すると、IDは表示から表示されないものに変更され、表示されます
2。マウスがID2からID1に移動すると、ID2の表示が非表示になり、表示されます
私が望んでいるのは、マウスがID1またはID2で移動するとき、ID2が変更せずに現れ続けることです。
<script type = "text/javascript" src = "https://code.jquery.com/jquery-1.12.4.js"> </scrip> <div id = "id1"> <div id = "id2"> </div> </div> <スクリプトtype = "text/javascript"> $( "#id1")。mouseover(function(){$(this).children()。fadein(1000);})。mouseout(function(){$(this)問題解決策
最初の問題分析では、マウスがID1からID2に移動したとき、マウスがID2からID1に左に、ID1に対してマウスアウトイベントがトリガーされたため、ID2の表示が非表示になったことでした。その後、マウスはID2に移動し、ID2でマウスオーバーイベントがトリガーされました。バブルメカニズムにより、ID2のマウスオーバーがID1に泡立つ前に、ID1のマウスオーバーイベントがトリガーされ、ID2が非ディスプレイから表示に変更されました。同様に、マウスがID2からID1に移動すると、ID2に対してマウスアウトイベントがトリガーされます。または、マウスアウトイベントがID1に送信されるバブルメカニズムのため、ID2はディスプレイから非ディスプレイに変更されます。その後、マウスがID1に移動する前に、マウスオーバーイベントがトリガーされ、ID2が表示されません。
マウスがID1からID2に移動したときに、上記の問題はID1からマウスをブロックすることで解決する必要があるようです。マウスがID2からID1に移動すると、ID2からID2からID1にマウスをブロックし、ID1の上に泡立つマウスをID2から排除します。その後、泡を防ぐだけで問題を解決することはできません。
このような問題を解決するために、jQueryはマウスエンテルとムーセリーブの方法を提供します。そのため、JSコードは次のように変更され、問題は非常にうまく解決されました。
$( "#id1")。mouseenter(function(){$(this).children()。fadein(1000);})。museleave(function(){$(this).children().fadeout(1000);});多くの場所で、マウスエンター、ムーセリーブ、マウスオーバー、マウスアウトを紹介しているので、コピーして貼り付けました。
/*******************************************/
1.マウスオーバーとマウスエンター
マウスポインターが選択した要素を通過するか、その子要素を通過するかに関係なく、マウスオーバーイベントはトリガーされます。
マウスエンターイベントは、マウスポインターが選択した要素を通過する場合にのみトリガーされます。
2.マウスアウトとムーセリーブ
マウスアウトイベントは、マウスポインターが選択した要素を離れるか、任意の子要素を離れるかに関係なくトリガーされます。
Mouseleaveイベントは、マウスポインターが選択した要素を離れるときにのみトリガーされます。
/*******************************************/
この現象は確かにこの現象ですが、プロセスは少しあいまいです。私の理解は次のとおりです。
マウスポインターが選択した要素に移動すると、マウスオーバーイベントがトリガーされます。マウスポインターが選択された要素から子要素に移動すると、選択した要素のマウスアウトイベントが最初にトリガーされ、次に子要素のマウスオーバーイベントが選択された要素にバブルされることを誰もが知っています。現時点では、選択した要素が最初にマウスアウトイベントを実行し、次にマウスオーバーイベントを実行することに相当します。
検証のために、コードを次のように変更します
<script type = "text/javascript" src = "https://code.jquery.com/jquery-1.12.4.js"> </scrip> <div id = "id1"> <div id = "id2"> </div> </div> <スクリプトtype = "text/javascript"> $( "#id1")。mouseover(function(){// $(this).children()。fadein(1000); console.log( 'a');})マウスをページからID1に移動してから、ID1からID2に移動します。コンソール出力は次のとおりです。
ID1は、マウスオーバー、マウスアウト、マウスオーバーイベントと呼ばれていることがわかります。これは、上記のものとまったく同じです。
MouseenterおよびMouseleave実装分析
原則分析
上記の分析から、マウスエンテルとムーセリーブの効果を達成するために、マウスが選択した要素から子要素に移動すると、選択した要素がマウスアウトイベントを実行せず、サブクレスのバブルがマウスオーバーイベントを実行しないことがわかります。マウスが選択された要素要素要素から選択された要素に移動する場合、選択した要素はマウスオーバーイベントを実行しません。また、サブクラスが泡立つマウスアウトイベントを実行しません。
上記の効果を実現するには、マウスオーバーおよびマウスアウトイベントターゲットノードの関連ノードの属性を判断するために使用されるイベントオブジェクトの属性関連ターゲットが必要です。簡単に言えば、マウスオーバーイベントがトリガーされると、関連タルゲット属性はマウスが残したノードを表し、マウスアウトイベントがトリガーされると、マウスが移動するオブジェクトを表します。 MSIEはこのプロパティをサポートしていないため、プロパティを置き換えました。さらに、オブジェクトが別のオブジェクトに含まれているかどうかを判断するためのcontinesメソッドも必要です。
このようにして、マウスが動くとき、次の2つを判断する必要があります
1.マウスオーバーを呼び出すと、関連標準が選択された要素の子要素であるかどうかを判断する必要があります。その場合、それは実行されません(選択した要素要素要素から選択した要素に移動すると、マウスオーバーは実行されません。選択した要素から選択した要素の子要素に移動すると、バブルドマウスオーバーは実行されません)。
2。マウスアウトに電話すると、関連する標的の子要素が選択されているかどうかを判断する必要があります。その場合、それは実行されません(選択した要素要素要素から選択した要素に移動すると、子要素から泡立つマウスアウトが実行されません。選択した要素から選択した要素の子要素に移動すると、マウスオーバーは実行されません)。
実装プロセス
2つの要素間に包含関係があるかどうかを判断する
contains関数は、次のようにjqueryにカプセル化されています
次のように簡素化できます
// 2つのaがbfunctionが含まれているかどうかを判断します(a、b){return a.contains? a!= b && a.contains(b):!!(a.comparedocumentposition(b)&16);}CompartumentPositionの紹介
この方法は、DOMレベル3仕様の一部であり、2つのDOMノード間の相互位置を決定できます。この方法は、.contains()よりも強力です。この方法の可能なアプリケーションの1つは、DOMノードを詳細かつ正確な順序にソートすることです。 nodea.comparedocumentposition(nodeb)によって返される情報は、次のように説明されています。
ビット番号の意味
上記を通して、ノードAがノードBを含む場合、16が返され、16と16 = 1が返され、他のケースでは結果が0になるため、A.CompareDocumentPosition(b)&16としてそれを書くべき理由を理解できます。
互換性のためにrelatedTargetを取得します
さまざまなブラウザと互換性があるため、jQueryソースコードを参照して、次のコードを記述して、マウスオーバーおよびマウスアウトイベントターゲットノードの関連ターゲットを取得します。
関数getRelated(e){var related; var type = e.type.tolowercase(); //ここでイベント名を取得します(type == 'mouseover'){related = e.RelatedTarget || e.Fromelement} else if(type = 'mouseout'){関連= e.RelatedTarget || e.Tolement}リターン; }マウスオーバーとマウスアウトを改善します
マウスオーバーとマウスアウトを改善して、マウスエンサーとムーセリーブ効果の改善を実現します。すべてのコードは次のとおりです。
<!Doctype html> <html> <head> <title> </title> </head> <body> <div id = "id1"> <div id2 "> </div> </div> <script type =" text/javascript "src =" https://code.jquery.com type = "text/javascript"> // 2つのaがbfunctionが含まれるかどうかを判断します(a、b){return a.contains? a!= b && a.contains(b):!!(a.comparedocumentposition(b)&16);} function getRelated(e){var related; var type = e.type.tolowercase(); //ここでイベント名を取得if(type = 'mouseout'){related = e.relatedTarget || element} return related; } $(function(){$( "#id1")。マウスオーバー(function(e){//マウスがid1 var関連= getrelated(e); //関連がid1の子要素ID2に移動する場合、つまり、子要素ID2からID1に移動するか、ID1からID1に関連するID1から、ID1に関連するID1から、ID1に関連しています。 if(this!= related &&!contains(this、related)){console.log( 'mouseover');}})要素、操作は実行されません。それ以外の場合は、対応する操作が実行されます(this!= related &&!contains(this、related)){console.log( 'mouseout');}});}); </script> </body> </html> </html>次の図に示されているように、テスト、マウスの移動ルート
コンソールからわかるように、現時点でマウスオーバーとマウスアウトには、マウスエンテルとムーセーブ効果が完全に装備されています。
コードのカプセル化
そのような操作を実行するたびにjQueryをロードするか、多くの代表者を書く必要がある場合、それは退屈な作業になります。将来の操作を促進するために、適切なパッケージが実行され、jQueryがシミュレートされ、独自のマウスエンターとムーセリーブを生成します。次のように、コードはdqmouse.jsファイルにカプセル化されます。
(function(w){var dqmouse = function(obj){// function body return new dqmouse.fn.init(obj);} dqmouse.fn = dqmouse.prototype = {//拡張プロトタイプオブジェクトOBJ:null、dqmouse: "1.0.0"、init(obj){obj = abj; this;}、contains:function(a、b){return a.contains(b):!!(a.comparedocumentposition(b)&16);}、function(e){var related; var type = e.type.tolowercase(); if(type == 'mouseover'){related = e.relatedTarget || e.fromelement} else if(lated = e.relatedTarget || element} return related} {var obj = this.obj;関連= _self.getRelated(e); !_self.contains(obj、related)){fn();}} return _ self;}} dqmouse.fn.init.prototype = dqmouse.fn; window.dqmouse = window。$$ = dqmouse;})(window);呼ばれるソースファイルは次のとおりです。
<div id = "id1"> <div id = "id2"> </div> </div> <script = "text/javascript" src = "dqmouse.js"> </script> <script type = "text/javascript"> var id1 = document.getElementById( 'id1'); $$(id1)。 </script>
上記は、編集者が紹介したJSでマウスオーバーとマウスアウトが複数回トリガーする問題を解決する方法に関する関連するコンテンツです。私はそれが誰にでも役立つことを願っています!