传统方法:

且看下面代码,

function addLoadEvent(func){var oldload=window.onload;if(typeof window.onload!="function"){window.onload=func;}else{window.onload=function(){oldload();func();}}
}

至此,使用addLoadEvent方法可以不断地为window.onload事件添加方法。

另外,把这个函数小改一番便可以使用到其他事件上。

DOM 2 提供的新的api

node.addEventListener方法。

具体看代码:

var btn=document.getElementById("btn");//btn是一个按钮
btn.addEventListener("click",doSomething1,false);
btn.addEventListener("click",doSomething2,false);

于是,点击btn按钮,会执行两个方法。

貌似问题得到圆满解决,可惜不是。因为IE会跳出来说:“IE没有这个方法”。

在IE上的实现是这个样子的:

var btn=document.getElementById("btn");//btn是一个按钮
btn.attachEvent("onclick",doSomething1);
btn.attachEvent("onclick",doSomething2)

功能上完全一样的两个函数,名字不同,参数不同。(注意,addEventListener是“click”,attachEvent是“onclick”)

怒摔。

虽然这是个很容易就解决的问题,但总要被坑一把才能发现。IE和chrome打架真是殃及无数池鱼。

我们聪明机智的程序员总可以用经典思路去解决这种“经典问题”:

function addEventLoad(node,func){if(node.addEventListener){node.addEventListener("click",func,false);}if(node.attachEvent){node.attachEvent("onclick",func);}
}

或者再进一步:

function addEventLoad(object,eventName,func){if(object.addEventListener){object.addEventListener(eventName,func,false);}if(object.attachEvent){object.attachEvent("on"+eventName,func);}
}
继续深入(重要)

看看btn的代码:

<button id="btn" title="this is a button">btn</button>

然后是两个事件函数的代码:

function do1(){alert(this.title);
}
function do2(){alert(this.title);
}

然后放出整个测试页面的代码:

<!DOCTYPE HTML>
<html><head><script>window.onload=function(){var btn=document.getElementById("btn");btn.onclick=function(){alert("btn1");};addEventLoad(btn,do1);addEventLoad(btn,do2);}function addEventLoad(node,func){if(node.addEventListener){node.addEventListener("click",func,false);}if(node.attachEvent){node.attachEvent("onclick",func);}}function do1(){alert(this.title);}function do2(){alert(this.title);}</script></head><body><button id="btn" title="this is a button">btn</button></body>
</html>

此页面在chrome上运行,点击按钮会弹出3个警告框,分别是:

“btn1”,“this is a button”,“this is a button”

但在IE上运行则是:

“btn1”,“undefined”,“undefined”

IE真是虐我千百遍。

经查阅:IE没有实现DOM Level 2(比如document.addEventListener就属于DOM Level 2)。IE有自己的事件处理框架。所以在IE中,事件处理函数为这个事件框架所有,而不属于XHMLT页面上通过点击事件或鼠标移动事件激活的一个对象。也就是说,do1和do2中的this关键字,在chrome中就是指那个按钮,在IE中就是指IE事件框架。

至此,看起来问题难以解决,真是绝望。

但正所谓天无绝人之路,其实,事件处理程序会从attachEvent()和addEventListener()得到一个Event对象,这个对象有两个很有用的属性:

“type”:提供所触发事件的事件名,比如“click”

“target”:指向事件的目标,即页面上被激活的对象

然后,我们发现问题又来了:chrome和ie的这个Event对象是不同的。在chrome中Event对象的target,在ie中则是srcElement。

但这难不倒我们,看下列函数:

function getActiveObject(e){var obj;if(!e){          //较早版本的IE不会发送这个对象obj=window.event.srcElement;}else if(e.srcElement){obj=e.srcElement;}else{obj.e.target;}return obj;
}

其中e就是那个Event对象。

另外,为了让事件处理函数使用这个Event对象,我们需要在其参数列表上加一个变量,比如这样

do1(e){}

然后我们看看经过修改的完整测试页面:

<!DOCTYPE HTML>
<html><head><script>window.onload=function(){var btn=document.getElementById("btn");btn.onclick=function(){alert("btn1");};addEventLoad(btn,do1);addEventLoad(btn,do2);}function addEventLoad(node,func){if(node.addEventListener){node.addEventListener("click",func,false);}if(node.attachEvent){node.attachEvent("onclick",func);}}function do1(e){var obj=getActiveObject(e)alert(obj.title);}function do2(e){var obj=getActiveObject(e)alert(obj.title);}function getActiveObject(e){var obj;if(!e){        //较早版本的IE不会发送这个对象obj=window.event.srcElement;}else if(e.srcElement){obj=e.srcElement;}else{obj.e.target;}return obj;}</script></head><body><button id="btn" title="this is a button">btn</button></body>
</html>

至此,此页面在Chrom和IE上都可以得到想要的东西。

转载于:https://my.oschina.net/evanyan/blog/306589

论如何做好IE和Chrome互殴时的一条好池鱼之事件绑定篇相关推荐

  1. 喜茶多名员工与外卖小哥互殴 喜茶官方:辞退!

    最近奶茶圈的"戏"也很多,不少都出圈到引发吃瓜群众们热议. 日前有报道称喜茶济南店发生了一起员工与外卖小哥互殴事件,起因是外卖小哥等了1个小时才拿到外卖,引发不满导致双方动手. 喜 ...

  2. 字节辟谣被裁员工与 HR 互殴;苹果头显多个新功能曝光;谷歌希望 RISC-V 成为 T1 级 Android 架构|极客头条...

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews ...

  3. 字节辟谣被裁员工与 HR 互殴;苹果头显多个新功能曝光;谷歌希望 RISC-V 成为 T1 级 Android 架构|极客头条

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews ...

  4. 如何用Python面向对象实现盖伦和瑞文互殴?

    首先我们来定义一个英雄类 #定义英雄类,等一下提供盖伦和瑞文继承 class Hero:#__init__为初始化方法,在对象实例化的时候自动调用def __init__(self,nickname, ...

  5. 恐龙跳一跳游戏python_在esp8266上面开发一款chrome浏览器离线时可玩的那款恐龙跳仙人掌的游戏...

    chrome offline game on esp8266 当前更新到2.0版本 以下是1.0版本 在esp8266上面开发一款chrome浏览器离线时可玩的那款恐龙跳仙人掌的游戏. 原型 游戏的原 ...

  6. 中文简繁体互转时的语义识别AI

    中文简繁体互转时,使用直译很简单,Delphi中使用LCMapStringW这个API. 但是如果要追求完美,考虑两岸用词习惯,就需要考虑"语义",有两种情况: (1)字还是基本是 ...

  7. 关于 Chrome插件安装时程序包无效:CRX_HEADER_INVALID 的解决方法

    关于 Chrome插件安装时程序包无效:"CRX_HEADER_INVALID" 的解决方法 打开chorme的扩展程序(设置-->更多工具-->扩展程序)chrome ...

  8. 安装Chrome插件SwitchySharp时出现的“程序包无效”问题

    安装Chrome插件SwitchySharp时出现的"程序包无效"问题 话不多说官网下载地址:https://www.switchysharp.com/install.html 进 ...

  9. 解决chrome插件安装时出现的“程序包无效”问题信息:程序包无效。

    今天想去chrome应用商店加载一个插件,发现有错误信息:程序包无效.详细信息:"Cannot load extensionwith file or directory name _. Fi ...

  10. [亲测好用]解决Chrome插件安装时出现的“程序包无效”问题

    问题描述: 使用Chrome加载下载的.crx 文件,在将crx拖拽到Chrome扩展程序时(chrome://extensions/),提示"程序包无效". 解决方法: 修改.c ...

最新文章

  1. 进程、线程、多线程相关总结
  2. MariaDB: ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (111 Connection refused)
  3. 破解石碑(区间动规)
  4. Hyperscan-5.1.0 安装
  5. [转载]VC6下安装STLport-5.2.1
  6. hdu4912 LCA+贪心
  7. 【计算理论】计算理论总结 ( 泵引理 Pumping 证明 ) ★★
  8. 可怕又可笑的看病经历
  9. web前端技术分享:多行文本溢出问题解决方案
  10. 听说做程序员年入百万,能不能带带你表弟?
  11. 他在 Stack Overflow 提问如何黑掉Stack Overflow,结果成了
  12. 246. Strobogrammatic Number
  13. 计算机专业行业分析300字,计算机专业毕业生自我鉴定范文300字(精选5篇)
  14. qt mdi 子窗口关闭再打开_QT 信号的使用方法
  15. vb入门教程 经验分享
  16. 一键切换网卡ip v1.0
  17. Kylo 之 spark-job-profiler 源码阅读
  18. easypoi 语法_【英语语法】一般过去时(附视频讲解)
  19. WebUI自动化框架 - 数据驱动(ddt、paramunittest)
  20. linux系统文件空间清理摸9z,Linux下的文件加密

热门文章

  1. 阿里云商标注册查询入口(支持图形检索/45分类注册风险)
  2. luogu4093 序列 (cdq分治优化dp)
  3. win10安装Visual Studio2019时卡在了提取文件处
  4. sagemath_同余运算总结
  5. 苹果plus html,iPhoneX 苹果8 8PLus区别:所有功能参数 最详细全面对比
  6. 苹果计算机取消用户名和密码进入不,苹果手机刷机过后进不了桌面要id账号和密码但是忘记了怎么处理?...
  7. 如何免费获取国外硕博学位论文全文资源
  8. 刚读博士想退学?如何避免博士毕业不了?
  9. 适合记录日常工作的便签如何在电脑桌面上添加
  10. FPGA-小梅哥时序约束