用原生js寫一個hover函數,用於實現jquery中的hover事件 http://hi.baidu.com/570851835/item/ad513fdbd7c5d995260ae78f


jquery 中有一個hover事件十分的有用,是javascript中的onmouseover和onmouseout無法輕易實現的,沒有去看過jquery對 hover事件的實現方法,按我自己的思路來完成這個方法。首先,應該認定jquery的hover方法一定是用onmouseover和 onmouseout方法包裝實現的,因為在極簡易的情況下,onmouseover和onmouseout和hover是沒有區別的例如:

<div id="dd" style="width:100px; height:100px; overflow:hidden; border:1px solid #3d3d3d; position:relative;">
</div>

此時用如下代碼:

  1. $("#dd").hover(function(){alert("進來了");},function(){alert("出來了");});

  2.document.getElementById("dd").onmouseover=function(){alert("進來了");}; document.getElementById("dd").onmouseout=function(){alert("出來了");};

以上兩段代碼是相同的

但是,如果在dd上添加一個子層dd2的話,情況就不一樣了如下:

<div id="dd" style="width:100px; height:100px; overflow:hidden; border:1px solid #3d3d3d; position:relative;">
<div id="dd2" style="width:50px; height:50px; overflow:hidden; background-color:#cccccc; position:absolute; left:30px; top:30px;"></div>
</div>

此時用上面的兩段代碼,表現出來的效果就差很多了。很多情況下,用jquery的hover方法才是我們想要得到的效果。為什么會造這個差別呢?

最 開始我認為會不會是jquery在寫hover方法的時候,寫了一個對整個dom進行檢查的方法鼠標一直處在dd元素內,即當鼠標滑入dd2 時,jquery會對dd2的父級節點進行遍歷來確認dd2是不是dd的子元素。這個理論上是可以實現hover方法的,但是開銷太大了,是個不好的方 法,jquery不可能是用這樣的方法吧。自己也嘗試了一下驗證jquery不是用這個方法實現的,驗證的方法其實很簡單用如下代碼:

<div id="dd" style="width:100px; height:100px; border:1px solid #3d3d3d; position:relative;">
<div id="dd2" style="width:50px; height:50px; overflow:hidden; background-color:#cccccc; position:absolute; left:300px; top:300px;"></div>
</div>

js代碼如下:

  1. $("#dd").hover(function(){alert("進來了");},function(){alert("出來了");});

  2. $("#dd2").hover(function(e){e.stopPropagation();});$("#dd").hover(function(){alert("進來了");},function(){alert("出來了");});

運行的結果是代碼1,在鼠標滑入滑出dd2時,都會彈出提示;而運行代碼2時,滑入滑出dd2都無任何提示。

這表示jquery不是用剛才想的笨方法實現的,同時可以知道的一點是jquery是通過鼠標事件的冒泡完成hover事件的。

返 回到onmouseover和onmouseout來,因為鼠標事件(event)在一個父容器內滑過它的子容器仍然會觸發父容器的onmouseout 事件,但是因為事件冒泡的存在,瞬間父容器又會發生成onmouseover事件。這就是說,如果可以延遲onmouseout事件的觸發,是可以實現 hover事件的。但是呢,延遲事件是不可能完成的,可以完成的是,對事件函數的延遲處理,只要對onouseout事件函數進行延遲與鼠標有沒有回到父 容器的onmouseover事件的判斷處理的判斷,基本上可以完成hover方法。有了這個思路,馬上寫出一個hover的代替函數

function bind(elem,ev,callback)
 {
  if(document.all)
  {
   elem.attachEvent("on"+ev,callback);
  }else{
   elem.addEventListener(ev,callback,false);
  }
 }
 function unbind(elem,ev,callback)
 {
  if(typeof(callback)=="function")
  {
   if(document.all)
   {
    elem.detachEvent("on"+ev,callback); 
   }else{
    elem.removeEventListener(ev,callback,false);
   }
  }else{
   if(document.all)
   {
    elem.detachEvent("on"+ev); 
   }else{
    elem.removeEventListener(ev,false);
   }
  }
 }
 function hover(elem,overCallback,outCallback){//實現hover事件
  var isHover=false;//判斷是否懸浮在上方
  var preOvTime=new Date().getTime();//上次懸浮時間
  function over(e){
   var curOvTime=new Date().getTime();
   isHover=true;//處於over狀態
   if(curOvTime-preOvTime>10)
   {//時間間隔超過10毫秒,認為鼠標完成了mouseout事件
    overCallback(e,elem);
   }
   preOvTime=curOvTime;
  }
  function out(e)
  {
   var curOvTime=new Date().getTime();
   preOvTime=curOvTime;
   isHover=false;
   setTimeout(function(){
    if(!isHover)
    {
     outCallback(e,elem);
    }
   },10);
  }
  bind(elem,"mouseover",over);
  bind(elem,"mouseout",out);
 };

運行以下代碼,正好就是jquery的hover方法

<div id="dd" style="width:100px; height:100px; border:1px solid #3d3d3d; position:relative;">
<div id="dd2" style="width:50px; height:50px; overflow:hidden; background-color:#cccccc; position:absolute; left:30px; top:30px;"></div>
</div>

hover(document.getElementById("dd"),function(){document.getElementById("dd2").innerHTML="進來了";},function(){alert("出來了");});


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM