日期:2014-05-16  浏览次数:20364 次

JS控制document全局级别鼠标事件
   这几天项目赶着code freeze, QA那边又报来一堆前台页面的bug, 在正常人的印象中我们都认为页面的bug都很简单,但是实际上改起来着实是废了极大心思,实践证明前台的bug需要考虑的东西实在太多了,而且还要保证我们的项目兼容IE7/8/9,FireFox, Chrome, Safari, 真的是恶心的不是一点。相关的文章:http://txterran.iteye.com/blog/1837394
   这几天改的datepicker失去焦点的bug就是一典型案例:
   背景介绍: datepicker组件是由一个<ul>标签里的子<li>通过hover事件添加的,而这个<ul>也是由hover展现的,实现这个组件已耗费大量精力,略去不表。
   bug描述: 如果datepicker所在的由<li> hover出来的div如果鼠标移出,则自动将datepicker关闭,但是这个div里的第二个datepicker如果在打开的情况下移出鼠标,它并没有被自动关闭。
   解决方法: 第一印象是挺简单的,无非就是在datepicker所在的div上加一个onmouseout事件罢了,如果鼠标移出了这个div则调它的api将datepicker hide住,实践证明完全不行,因为如果单纯判断div的onmouseout后,直接导致datepicker一旦点击则全部都被关闭了,原因就是datepicker并不是这个div内的元素,光这个问题快研究了一天,试了各种办法,无方最后无奈重写了它的原生hover函数:

<script type="text/javascript">
 $j('.uidatepicker').hover(functions.panelFocusForDatePicker,
       functions.panelBlurForDataPicker);
</script>

这两个函数对象就不列了,里面又是纠结的重新手写了一大堆css加样式。
After testing, 真正恶心的问题才刚刚出现,为什么上面的datepicker可以正常移出div就关闭,而下面的那个不行呢?苦逼的加alert一行行跟code,最后发现是下面那个家伙一旦触发popup出来就必须要鼠标先去hover它才会关闭,本质上原因是datepicker中默认选择的是当前今天,而datepicker在初始化时设置了最大天数就是到今天为止,而源码里肯定有地方做了限制,不能选择最大天,所以导致datepicker一直不能自动关闭(因为它要你重新选择一天才行),这回真没招了,不能让我去改源码吧。
   苦思无果,想了个很巧的办法,我在全局的document级别注册一个mousemove事件,去专门判断最外层的div样式,如果判断到他不存在了,则用js把那两个datepicker关掉:

<script type="text/javascript">
$j(document).mousemove(function(event) {
  var position = $j("#topExpensesForm\\:dateRangeDiv").css("left");
  if(position != '0px'){
     $j('.startDateRange').datepicker('hide');
     $j('.endDateRange').datepicker('hide');
  }
});

哦了,重新test,通过!聊聊几行code,在document级别加一个这个事件终于fix掉了这个lousy的bug,真心值得记录下来。