zwhu / blog

嘛,写 blog 也要遵守基本法。
MIT License
66 stars 2 forks source link

Javascript 中的惰性加载 #22

Open zwhu opened 8 years ago

zwhu commented 8 years ago

今天一个初学者问我怎样在老的浏览器下实现通用的事件绑定函数。这个问题挺简单,我随手写了如下的函数:

var addEvent = function(el, type, handler) {
  if(window.addEventListener) {
    return el.addEventListener( type, handler, false)
  } else if(window.attachEvent) {
    return el.attachEvent('on' + type, handler)
  }
}

但是这个函数写完之后我就感觉到有些问题,那就是每次调用的时候都要对浏览器进行嗅探,即执行 if 判断。虽然执行 if 不会对计算机造成太大开销,但是作为一个有追求的程序员,怎会放弃如此可以优化的机会。

所以回到问题的原点,为什么要对浏览器进行嗅探?因为不同浏览器有不同的兼容性。那么我们只要嗅探一次且要保证在没有调用过这个函数的情况下不进行嗅探可不可以?当然可以!下面的代码就是利用惰性加载函数的方法:

var addEvent = function(el, type, handler) {
  if(window.addEventListener) {
    addEvent = function(el, type, handler) {
      el.addEventListener( type, handler, false)
    }
  } else if(window.attachEvent) {
    addEvent = function(el, type, handler) {
      el.attachEvent('on' + type, handler)
   }
  }
  addEvent.apply(null, arguments)
}

第一次调用 addEvent 的时候会对浏览器进行嗅探,然后把嗅探之后的结果再重新替换掉 addEvent。早期的 Redux 的 applymiddleware 实现也是使用这个方法。