相對定位父子項目觸發mouseover和mouseout事件實驗

來源:互聯網
上載者:User

最近做的一個項目中有個功能是滑鼠移動到某一塊id為A,然後A的子項目id為B在下方緊貼著父元素A顯示出來,B裡面的內容是滑鼠移動到A元素上才請求服務端擷取資料。

我使用了mouseover,mouseout事件,採用jquery的on方法。大致如下

$(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"});});
顯示大概是這樣

  可是TMD我發現我滑鼠移動到A上出現B後,滑鼠在兩者間滑動,網路在不停的請求子項目的資料,也就是說在不停的觸發A元素的mouseover事件,然後頁面中就卡幾下。

當時項目發布比較急,就沒管,後來周末一大早,心頭很悶,大冬天爬起來洗個澡開啟電腦就開始研究這個問題。


第一步:

代碼:

<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>

我的滑鼠從father元素滑入,出現了child元素,再從father元素滑到child元素中,出現如下情況


也就是說father元素先觸發mouseover事件,當滑鼠進入child元素後觸發了mouseout事件,並且再次觸發了mouseover事件。

這種情況只有一種解釋,就是從father滑入child時,father元素觸發了mouseout事件的,進入child元素觸發了child的mouseover事件,並且通過事件冒泡,進而觸發了father元素的mouseover事件。

第二步:

為了證實上述的解釋,接下來做另一個實驗。

<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>

出現如下記錄


動作和第一步中的動作一致,但是我使用了阻止冒泡,所以father元素就沒有觸發了第二次的mouseover事件,並且此時child元素由於father元素觸發了mouseout事件將child的display設為none,並且在child觸發了mouseover事件時沒有冒泡觸發father的此事件,所以沒有將child的display設為block,所以child不再顯示了。

也就是說當滑鼠在father和child之間滑動時,是通過father不斷的觸發mouseover事件才使得child元素一直顯示,其實是child一直在迴圈消失又再顯示的過程,肉眼無法分辨,所以看到child會一直顯示。

是不是這樣呢?我們接著看

第三步:

代碼:

<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>

記錄如下:


果然,我的動作依然是從father滑入,然後向下滑入到child元素內,觸發的事件如所示。


到這裡我已經明白我項目中的那個問題產生的原因,但是怎麼解決呢,我希望在A和B元素間滑動時不要再重複請求服務端資料,可是A的mouseover事件在一直觸發,怎麼辦呢?突然我想起了target....

第三步:


代碼:

<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>

同樣的滑鼠移動操作,產生結果如下:


target是某次事件觸發的原始元素,也就是第一個觸發此事件的元素,然後冒泡,引起上階項目觸發此事件。

中清晰記錄了事件觸發的源頭。“father mouseover,target:child”這條記錄說明father的mouseover事件觸發的源頭是child。

那麼在我的項目中的那個問題,我可通過觸發事件的源頭來決定是否請求服務端的資料,修改大致如下:

$(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");});









相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.