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

posted on 2013-11-07 09:13  javascript程序员  阅读(5621)  评论(1编辑  收藏  举报