JavaScript跨浏览器绑定事件函数的优化

转载自:http://www.cnblogs.com/yugege/p/5169998.htmlhtml

 JavaScript做为一门基于事件驱动的语言(特别是用在DOM操做的时候),咱们经常须要为DOM绑定各类各样的事件。然而,因为低版本的IE的不给力,在绑定事件和移除事件监听上都不同凡响,咱们经常须要本身封装一个跨浏览器绑定(移除)事件的函数。跨浏览器添加(移除)DOM事件的一种很是经典的实现代码以下:chrome

复制代码
//跨浏览器添加事件
function addHandler(target, eventType, handler) {
  if(target.addEventListener) { //DOM2 events
    target.addEventListener(eventType, handler, false);
  } else { //IE
    target.attachEvent("on" + eventType, handler);
  }
}
 
//跨浏览器移除事件
function removeHanler(target, eventType, handler) {
  if(target.removeEventListener) { //DOM2 events
    target.removeEventListener(eventType, handler, false);
  } else { //IE
    target.detachEvent("on", eventType, handler);
  }
}
复制代码

    上面代码的实现思路是,首先判断浏览器是否支持DOM2的事件,若是支持,就用addEventListener()进行添加事件,用removeEventListener来移除事件。若是不支持,那么默认就是低版本的ie浏览器了,并使用ie特有的方法。浏览器

    乍一看,上面的代码好像已经充分优化了。隐藏的性能问题在于每次函数调用时都会作重复工做——检测浏览器的类型。这是比较消耗性能,特别是你绑定大量事件,反复调用的时候。事实上,这是没必要要的,咱们只须要判断一次就行的了。由于一旦页面加载完成后,浏览器的类型已是肯定了的,不可能说,如今是IE,而后浏览着浏览着忽然就会变成了chrome的了。因此,咱们应该对上面代码进行优化,使其只须要检测一次浏览器。有两种方法能够实现只检测一次,下面分别来探讨一下这两种方法。
  第一种是,在第一次调用添加(移除)事件函数的时候,检测并决定使用哪一种方法来绑定或者移除事件,而后重写函数,用一个包含正确操做的新的函数覆盖旧的函数,而且在旧的函数最后调用该这个新的函数。上面代码改写后以下:
复制代码
//添加事件
function addHandler(target, eventType, handler) {
 
  //检测浏览器类型,而且重写addHanler方法
  if(target.addEventListener) { //DOM2
    addHandler = function(target, eventType, handler) {
      target.addEventListener(eventType, handler, false);
    };
  } else { //IE
    addHandler = function(target, eventType, handler) {
      target.attachEvent("on" + eventType, handler);
    };
  }
   
  //调用新的函数
  addHandler(target, eventType, handler);
}
 
//移除事件removeHanler
function removeHandler(target, eventType, handler) {
 
  //检测浏览器类型,而且重写removeHandler方法
  if(target.removeEventListener) { //DOM2
    removeHandler = function(target, eventType, handler) {
      target.removeEventListener(eventType, handler, false);
    };
  } else { //IE
    removeHandler = function(target, eventType, handler) {
      target.detachEvent("on" + eventType, handler);
    };
  }
 
  //调用新的函数
  removeHandler(target, eventType, handler);
}
复制代码

    须要注意的是,咱们在两个函数的最后一行,都调用了被重写了的新函数,好比addHandler(target, eventType, handler);和removeHandler(target, eventType,handler);这是必要的,由于咱们用新的函数覆盖了旧的函数,必需要在旧的函数里调用新的函数它才会执行一次。函数

    还有一种优化方法是,提早检测浏览器类型,并把正确的操做函数赋值给一个变量(或者说是使用函数表达式)。咱们能够使用一个三目条件运算符(?...:)来实现,代码以下:
复制代码
//绑定事件
var addHandler = document.body.addEventListener ?
          function(target, eventType, handler) { //DOM2
            target.addEventListener(eventType, handler,false);
          } :
          function(target, eventType, handler) { //IE
            target.attachEvent("on" + eventType, handler);
          };
//移除事件 var removeHandler = document.body.removeEventListener ?             function(target, eventType, handler) { //DOM2               target.removeEventListener(eventType, handler, false);             } :             function(target, eventType, handler) { //IE               target.detachEvent("on" + eventType, handler);             }
复制代码

    这种方法,比前面比前面那种更加的“积极”,由于他是在函数调用以前就已经去检测浏览器类型了,调用的时候立刻就能够正确的去绑定事件。性能

PS:
参考资料: Nicbolas C.Zakas 《High Performance JavaScript》;chapter 8 ;Don’t Repeat Work
该书目前好像只有英文版而尚未中文版的。若是有须要的能够Google一下,下载个电子版的来看一下
相关文章
相关标签/搜索