In A recently developed project, A function is to move the mouse to A piece of id as A, and then the child element id of A is B, which is closely followed by parent Element, the content in B is to move the cursor over element A to request the server to obtain data.
I used the mouseover and mouseout events and the jquery on method. Roughly as follows:
$(document).on("mouseover","#A",function(){ $(this).find("#B").css({"display":"block"}); $.get("***",null,function(data){ $(this).find("#B").html(data); })});$(document).on("mouseout","#A",function(){ $(this).find("#B").css({"display":"none"});});This is probably the case.
However, TMD, I found that when I move the mouse over A and B appears, the mouse slides between the two, and the network continuously requests data of sub-elements, that is, the mouseover event of Element A is continuously triggered, then there will be a few cards on the page.
At that time, the project was very urgent and I was not responsible. Later on the weekend, early in the morning, my mind was very stuffy. In the winter, I got up and took a bath and started to study the problem.
Step 1:
Code:
<script type="text/javascript" src="jquery.comjquery-1.10.2.min.js"></script><style>#father{width:200px;height:200px;background-color:red;position:relative;}#child{display:none;position:absolute;left:0;top:199px;width:100px;height:100px;background-color:yellow;}#record{width:300px;height:100px;border:1px solid blue;position:absolute;right:0;top:0;}</style><script>$(document).on("mouseover","#father",function(e){$("#record").append("father mouseover</br>");$(this).find("div").css({"display":"block"});});$(document).on("mouseout","#father",function(e){$("#record").append("father mouseout</br>");$(this).find("div").css({"display":"none"});});</script><div id="father"><div id="child" ></div></div><div id="record" ></div>
My mouse slides in from the father element, the child element appears, and then the father element slides into the child element. The following occurs:
That is to say, the father element triggers the mouseover event first. When the mouse enters the child element, the mouseout event is triggered and the mouseover event is triggered again.
There is only one explanation for this situation, that is, when the father element slides into child, the father element triggers the mouseout event, the child element triggers the child mouseover event, and the event bubbles, this triggers the mouseover event of the father element.
Step 2:
In order to confirm the above explanation, another experiment will be conducted.
<script type="text/javascript" src="jquery.comjquery-1.10.2.min.js"></script><style>#father{width:200px;height:200px;background-color:red;position:relative;}#child{display:none;position:absolute;left:0;top:199px;width:100px;height:100px;background-color:yellow;}#record{width:300px;height:100px;border:1px solid blue;position:absolute;right:0;top:0;}</style><script>$(document).on("mouseover","#father",function(e){$("#record").append("father mouseover</br>");$(this).find("div").css({"display":"block"});});$(document).on("mouseout","#child",function(e){e.stopPropagation();$("#record").append("child mouseout</br>");});$(document).on("mouseover","#child",function(e){e.stopPropagation();$("#record").append("child mouseover</br>");});$(document).on("mouseout","#father",function(e){$("#record").append("father mouseout</br>");$(this).find("div").css({"display":"none"});});</script><div id="father"><div id="child" ></div></div><div id="record" ></div>
The following record appears:
The action is the same as the action in step 1, but I used to prevent bubbles, so the father element did not trigger the second mouseover event, at this time, the child element sets the display of child to none because the father element triggers the mouseout event, and does not bubble when the child triggers the mouseover event to trigger the father event, therefore, the display of child is not set as a block, so child is no longer displayed.
That is to say, when the mouse slides between father and child, the child element is always displayed only when the father continuously triggers the mouseover event. In fact, the child element disappears and then appears in a loop, unable to distinguish with the naked eye, so the child will always be displayed.
Is that true? Let's continue.
Step 3:
Code:
<script type="text/javascript" src="jquery.comjquery-1.10.2.min.js"></script><style>#father{width:200px;height:200px;background-color:red;position:relative;}#child{display:none;position:absolute;left:0;top:199px;width:100px;height:100px;background-color:yellow;}#record{width:300px;height:100px;border:1px solid blue;position:absolute;right:0;top:0;}</style><script>$(document).on("mouseover","#father",function(e){$("#record").append("father mouseover</br>");$(this).find("div").css({"display":"block"});});$(document).on("mouseout","#child",function(e){//e.stopPropagation();$("#record").append("child mouseout</br>");});$(document).on("mouseover","#child",function(e){//e.stopPropagation();$("#record").append("child mouseover</br>");});$(document).on("mouseout","#father",function(e){$("#record").append("father mouseout</br>");$(this).find("div").css({"display":"none"});});</script><div id="father"><div id="child" ></div></div><div id="record" ></div>
The record is as follows:
Sure enough, I still slide from father and then down to the child element, as shown in the event triggered.
Here I have understood the cause of the problem in my project, but how can I solve it? I hope that the server data will not be repeatedly requested when elements A and B slide, however, the mouseover event of A is being triggered all the time. What should I do? Suddenly I think of target ....
Step 3:
Code:
<script type="text/javascript" src="jquery.comjquery-1.10.2.min.js"></script><style>#father{width:200px;height:200px;background-color:red;position:relative;}#child{display:none;position:absolute;left:0;top:199px;width:100px;height:100px;background-color:yellow;}#record{width:300px;height:100px;border:1px solid blue;position:absolute;right:0;top:0;}</style><script>$(document).on("mouseover","#father",function(e){$("#record").append("father mouseover,target:"+e.target.id+"</br>");$(this).find("div").css({"display":"block"});});$(document).on("mouseout","#child",function(e){//e.stopPropagation();$("#record").append("child mouseout,target:"+e.target.id+"</br>");});$(document).on("mouseover","#child",function(e){//e.stopPropagation();$("#record").append("child mouseover,target:"+e.target.id+"</br>");});$(document).on("mouseout","#father",function(e){$("#record").append("father mouseout,target:"+e.target.id+"</br>");$(this).find("div").css({"display":"none"});});</script><div id="father"><div id="child" ></div></div><div id="record" ></div>
The result of moving the mouse is as follows:
Target is the original element triggered by an event, that is, the first element that triggers this event, and then bubbles, causing the parent element to trigger this event.
Clearly records the source of event triggering. The "father mouseover, target: child" record indicates that the source triggered by the father mouseover event is child.
In my project, I can determine whether to request data from the server by triggering the event source. The modification is roughly as follows:
$(document).on("mouseover","#A",function(e){ $(this).find("#B").css({"display":"block"}); var flag=parseInt($("#C").val()); if(e.target.id=="A"){ $.get("***",null,function(data){ $(this).find("#B").html(data); }) }});$(document).on("mouseout","#A",function(e){ $(this).find("#B").css({"display":"none"}); $("#C").val("true");});