欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-03-31 09:27:22
有一个需求要为document对象绑定click事件来是想隐藏提示框的交互功能,于是小白写了如下代码: 同事小铭看了看代码说: “首先,你为document 绑定了click事件,但是onclick是DOM0级事件,也就是说这种方式绑定的时间相当于为元素绑定了一个时间方法, 所以如果团队中的其他人再 ......

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

document.onclick = function(e) {
  e.preventdefault();
  if(e.target !== document.getelementbyid('myinput')) {
    hidepagealert();
  }
}


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

同事小铭看了看代码说:

“首先,你为document 绑定了click事件,但是onclick是dom0级事件,也就是说这种方式绑定的时间相当于为元素绑定了一个时间方法, 所以如果团队中的其他人再次通过这种方式为document绑定click事件时,就相当于重复定义了一个方法,会将你定义的click事件方法覆盖,如下列程序。”

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

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

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

兼容模式

// 外观模式实现

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方法的浏览器就可以放心的绑定多个事件了, 如下所示。”

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();
  }
}