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("出来了");});