有一个需求要为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();
}
}

最新文章

  1. mybatis 与 缓存
  2. Nginx-->基础-->理论-->002:Nginx进程介绍
  3. yourphp数据库介绍
  4. 剑指Offer 树的子结构
  5. java开发常用命令
  6. Adroid_Spinner_ArrayAdapter
  7. java基础(十七)集合(四)
  8. .Net里的Attribute 学习
  9. Codeforces Round #460 D. Karen and Cards
  10. 全废话SQL Server统计信息(2)——统计信息基础
  11. BZOJ_3083_遥远的国度_树链剖分+线段树
  12. [luogu P3313] [SDOI2014]旅行
  13. Mybaits动态Sql
  14. Django的datetime.timedelta类(Django编程-2)
  15. gispro发布vectortile笔记
  16. Jmeter干货 不常用却极其有用的几个地方
  17. shell 字符串提取数字
  18. eclipse tomcat路径更改后启动报错
  19. 浅谈ES6的let和const的异同点
  20. hdu1232 畅通工程 并查集的 应用

热门文章

  1. spring框架_AOP和注解
  2. 初次学习DropWizard框架——解决maven打包时出现没有主清单属性的问题
  3. IOS字符串截取保留小数点后两位
  4. [Android基础]Android四大组件之Activity总结
  5. 洛谷P4719 【模板】动态dp
  6. Java的常量接口思考,项目中的常量是放在接口里还是放在类里呢?
  7. RESTful API设计相关
  8. 原创 html动态表格
  9. <Android 应用 之路> 天气预报(二)
  10. LNK2005错误——重复定义错误