javascript设计模式(张容铭)学习笔记 - 外观模式绑定事件

有一个需求要为document对象绑定click事件来是想隐藏提示框的交互功能,因而小白写了以下代码:浏览器

document.onclick = function(e) {
  e.preventDefault();
  if(e.target !== document.getElementById('myinput')) {
    hidePageAlert();
  }
}


function hidePageAlert() {
  //隐藏提示框
}

同事小铭看了看代码说:dom

“首先,你为document 绑定了click事件,可是onclick是DOM0级事件,也就是说这种方式绑定的时间至关于为元素绑定了一个时间方法, 因此若是团队中的其余人再次经过这种方式为document绑定click事件时,就至关于重复定义了一个方法,会将你定义的click事件方法覆盖,以下列程序。”ide

document.onclick= function() {
  //其余开发人员从新为document绑定时间会覆盖前面定义的DOM0级click事件
}

“因此你这种方式是很危险的。所以你应该用DOM2级事件处理程序提供的方法addEventListener来实现,然而你知道老版本的IE浏览器(低于9)是不支持这个方法的,它支持的是attachEvent,固然若是有不支持DOM2级事件处理程序的浏览器,你只能用onclick事件方法来绑定事件。”spa

“那么有没有一个兼容全部浏览器的方式呢?” 小白追问。code

兼容模式对象

// 外观模式实现

function addEvent(dom, type, fn) {
  // 对于支持DOM2级事件处理程序addEventListener方法的浏览器
  if(dom.addEventListener) {
    dome.addEventListener(type, fn, false);
  // 对于不支持addEventListener 方法,可是支持attachEvent方法的浏览器
  }else if(dom.attachEvent) {
    dom.attachEvent('on' + type, fn);
  // 对于不支持addEventListener方法也不支持attachEvent方法,但支持on+'事件名'的浏览器
  }else{
     dom['on' + type] = fn;
  }
}

“这样咱们之后对于支持addEventListener 或 attachEvent方法的浏览器就能够放心的绑定多个事件了, 以下所示。”blog

var myInput = document.getElementById('myinput');

addEvent(myInput, 'click', function(){
  console.log('绑定第一个事件')
})

addEvent(myInput, 'click', function(){
  console.log('绑定第二个事件')
})

 

除此以外接口

“不过以前写的代码问题不止一个,以前说了,外观模式能够简化底层接口复杂性,也能够解决浏览器兼容性问题。而你以前写的代码除了绑定时间的问题外,另外两处问题是在其余IE低版本浏览器中不兼容 e.preventDefault 和 e.target。你也能够经过外观模式来解决。”事件

 

// 获取事件对象
var getEvent = function(event) {
  // 标准浏览器返回event,IE下window.event
  return event || window.event;
}

// 获取元素
var getTarget = function(event) {
  var event = getEvent(event);
  // 标准浏览器下event.target, IE下event.srcElement
  return event.target || event.srcElement;
}

// 阻止默认行为
var preventDefault = function(event) {
  var event = getEvent(event);
  // 标准浏览器
  if(event.preventDefault) {
    event.preventDefault();
  // IE 浏览器
  }else {
    event.returnValue = false;
  }
}

“有了上面的方法,咱们就能够用兼容的简单方式来解决上面的问题。”开发

document.onclick = function(e) {
  // 阻止默认行为
  preventDefault(e);
  // 获取事件源目标对象
  if(getTarget(e) != document.getElementById('myinput')){
    hideInputSug();
  }
}
相关文章
相关标签/搜索