addEventListener attachEvent和解决IE 6 7 8 this指向错误

[JS] addEventListener attachEvent和解决IE 6 7 8 this指向错误

 

电梯直达

1#

 php 发表于 2014/4/13 01:17 | 只看该作者 

标准浏览器中可以使用addEventListener()函数来给DOM元素绑定事件,使用removeEventListener()函数移除事件绑定,而IE6 IE7 IE8不支持addEventListener()和removeEventListener(),只能使用attachEvent()和detachEventListener()方法。IE从IE9开始支持addEventListener和removeEventListener.
addEventListener()和attachEvent()的区别主要有以下几点:

  • addEventListener(type,handler,capture)有三个参数,其中type是事件名称,如click,handler是事件处理函数,capture是否使用捕获,是一个布尔值,一般为false,这是默认值,所以第三个参数可以不写
    attachEvent(‘on‘+type,handler)有两个参数,其中type是事件名称,如click,第一个参数必须是onxxxx,handler是事件处理函数,IE6 IE7 IE8不支持事件捕获的,只支持事件冒泡。
    关于事件冒泡:如果一个元素和它的各层上级素都设置了相同的事件,比如click事件,那么冒泡是指,当用户点击鼠标后,先触发最底层元素的click事件,然后依次逐层触发上一级元素的click事件,就像泡泡从水底冒到水面一样。
    而与事件冒泡相反,事件捕获的顺序是,从页面的根元素开始依次逐层向下级触发事件。
    IE6-8只支持事件冒泡不支持事件捕获,Google Chrome/Firefox/Safari/Opera等标准浏览器支持事件捕获和事件冒泡。
    如果只想在最底层执行事件处理函数,阻止向上级元素冒泡,也就是说如果要阻止事件冒泡,标准浏览器可以使用stopPropagation(),IE6 7 8可以使用cancelBubble=true
  • addEventListener绑定的事件是先绑定先执行,attachEvent绑定的事件是先绑定后执行
  • 在IE6 IE7 IE8浏览器中,使用了attachEvent或detachEvent后事件处事函数里面的this指向window对象,而不是事件对象元素,文末有解决方案
  • 如果一个事件在绑定以后有解除绑定的需要,可以使用removeEventListener(),参数和addEventListener一样,IE6 IE7 IE8使用detachEvent函数,参数和attachEvent一样,注意,想要移除绑定的事件,则绑定事件时不能使用匿名函数,而需要将事件处事函数单独写成一个函数。否则无法移除绑定的事件函数,因为只绑定的事件才能移除,匿名函数和匿名函数是互相不相同的,即使代码完全一样,但本质上同一匿名函数的代码写两次就是两个不同的函数。
    下面以addEventListener为例
    1. <a id="xc">点击</a>
    2. <script type="text/javascript">
    3. function handler(){
    4. alert(this.innerHTML);
    5. }
    6. var object=document.getElementById(‘xc‘);
    7. xc.addEventListener(‘click‘,handler,false);//添加事件
    8. xc.removeEventListener(‘click‘,handler,false);//移除事件
    9. /*下面这种使用匿名函数的方式添加的事件是不能移除的,因为两个匿名函数虽然代码一样,但本质上他们是两个不同的函数
    10. xc.addEventListener(‘click‘,function(){
    11. alert(this.innerHTML);
    12. },false);
    13. xc.removeEventListener(‘click‘,function(){
    14. alert(this.innerHTML);
    15. },false);
    16. */
    17. </script>

    复制代码

  • 所添加的事件必须是事件对象支持的事件,比如给window对象添加click事件就不会成功,因为window没有click事件
  • 解决IE6 IE7 IE8 attchEvent this指向window的方法:

要解决IE6 IE7 IE8 attachEvent this指向错误,有至少以下三种方法:

  • 使用事件处理函数.apply(事件对象,arguments),代码如下
        以下代码仅适用于IE6 IE7 IE8
     这种方式的缺点是绑定的事件无法取消绑定,原因上面已经说了,匿名函数和匿名函数之间是互不相等的。

    1. <a id="xc">点击</a>
    2. <script type="text/javascript">
    3. var object=document.getElementById(‘xc‘);
    4. function handler(){
    5. alert(this.innerHTML);
    6. }
    7. object.attachEvent(‘onclick‘,function(){
    8. handler.call(object,arguments);
    9. });
    10. </script>

    复制代码

  • 使用事件源代替this关键字
    以下代码仅适用于IE6 IE7 IE8,这种方式完全忽略this关键字,但写起来稍显麻烦。
    1. <a id="xc">点击</a>
    2. <script type="text/javascript">
    3. function handler(e){
    4. e=e||window.event;
    5. var _this=e.srcElement||e.target;
    6. alert(_this.innerHTML);
    7. }
    8. var object=document.getElementById(‘xc‘);
    9. object.attachEvent(‘onclick‘,handler);
    10. </script>

    复制代码

  • 自己写一个函数完全代替attachEvent/detachEvent,并且支持所有主流浏览器、解决IE6 IE7 IE8事件绑定导致的先绑定后执行问题。
    下面是完美兼容addEventListener/removeEventListener和attachEvent/detachEvent的函数,支持Google Chrome/Firefox/Safari/Opera/IE 6 7 8 9 10 11等所有主流浏览器,能够完美解决IE6 IE7 IE8 this指向错误,能够纠正IE6 IE7 IE8中事件先绑定后执行的错误。
    为了避免代码被编辑器修改,请下载附件测试。不要直接复制下面的代码。
    注意,本函数是全局函数,而不是DOM对象的成员方法。
    1. <a id="xc">点击</a>
    2. <script type="text/javascript">
    3. /*
    4. * 添加事件处理程序
    5. * @param object object 要添加事件处理程序的元素
    6. * @param string type 事件名称,如click
    7. * @param function handler 事件处理程序,可以直接以匿名函数的形式给定,或者给一个已经定义的函数名。匿名函数方式给定的事件处理程序在IE6 IE7 IE8中可以移除,在标准浏览器中无法移除。
    8. * @param boolean remove 是否是移除的事件,本参数是为简化下面的removeEvent函数而写的,对添加事件处理程序不起任何作用
    9. */
    10. function addEvent(object,type,handler,remove){
    11. if(typeof object!=‘object‘||typeof handler!=‘function‘) return;
    12. try{
    13. object[remove?‘removeEventListener‘:‘addEventListener‘](type,handler,false);
    14. }catch(e){
    15. var xc=‘_‘+type;
    16. object[xc]=object[xc]||[];
    17. if(remove){
    18. var l=object[xc].length;
    19. for(var i=0;i<l;i++){
    20. if(object[xc][i].toString()===handler.toString()) object[xc].splice(i,1);
    21. }
    22. }else{
    23. var l=object[xc].length;
    24. var exists=false;
    25. for(var i=0;i<l;i++){
    26. if(object[xc][i].toString()===handler.toString()) exists=true;
    27. }
    28. if(!exists) object[xc].push(handler);
    29. }
    30. object[‘on‘+type]=function(){
    31. var l=object[xc].length;
    32. for(var i=0;i<l;i++){
    33. object[xc][i].apply(object,arguments);
    34. }
    35. }
    36. }
    37. }
    38. /*
    39. * 移除事件处理程序
    40. */
    41. function removeEvent(object,type,handler){
    42. addEvent(object,type,handler,true);
    43. }
    44. </script>
    45. <script type="text/javascript">
    46. function handler(){
    47. alert(this.innerHTML);
    48. }
    49. var object=document.getElementById(‘xc‘);
    50. addEvent(object,‘click‘,handler);
    51. //如果要测试绑定事件,请先删除下面这一行。
    52. removeEvent(object,‘click‘,handler);
    53. </script>

    复制代码

时间: 2024-07-30 11:18:56

addEventListener attachEvent和解决IE 6 7 8 this指向错误的相关文章

javascript中addEventListener(attachEvent)详解

addEventListener 有三个参数:第一个参数表示事件名称(不含 on,如 "click"):第二个参数表示要接收事件处理的函数:第三个参数为 useCapture.例子如下:  <button type="button">点击我</button> <img src="11 (6).jpg" alt="" style="display:block"> <s

解决 UnicodeDecodeError: &#39;ascii&#39; codec can&#39;t decode 错误

Ctrl + B 没结果. 查看控制台信息 如下: Running python -u -i C:\2.pyTraceback (most recent call last):  File ".\sublime_plugin.py", line 337, in run_  File ".\exec.py", line 154, in run  File ".\exec.py", line 45, in __init__UnicodeDecodeE

解决gremlin-dirver访问tinkerpop服务器提示序列化错误

解决gremlin-dirver访问tinkerpop服务器提示序列化错误 问题描述 程序集成了gremlin-driver,访问远程tinkerpop服务器,在执行创建节点操作时,返回如下错误栈: 2017-08-17 15:25:27.519 ERROR 13548 --- [n-driver-loop-3] o.a.t.g.d.Handler$GremlinResponseHandler : Could not process the response io.netty.handler.c

解决java代码测试http协议505错误

代码功能:通过java代码获取网页源代码: 所用工具:Myclipse8.5+tomcat6.0+浏览器 系统环境:windows xp旗舰版火狐浏览器版本: IE浏览器版本: 测试http协议有错误java代码如下. import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.

有效解决Win10用鲁大师ultra dma crc错误计数的恢复发方法

我们在win10系统电脑的使用中,鲁大师是很多小伙伴都在用的扫描的软件,我们可以直接使用来恢复我们的电脑,今天看到有小伙伴在使用的时候出现Win10用鲁大师ultra dma crc错误计数,这个问题怎么恢复呢,今天小编就来跟大家分享一下有效解决Win10用鲁大师ultra dma crc错误计数的恢复发方法. 具体的方法和详细的步骤如下: 原因分析 出现该情况有可能硬盘与主板接触不良,软件误报,或者硬盘质量问题等等. 解决方法: 1.把USB外界排查拔掉,换上一条质量好的SATA数据线,查看问

addEventListener || attachEvent

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>addevent</title> </head> <body style="height:9000px;"> <div style="position:fixed; top:0px; left:0p

怎么解决mysql不允许远程连接的错误

最近使用Navicat for MySQl访问远程mysql数据库,出现报错,显示"1130 - Host'xxx.xxx.xxx.xxx' is not allowed to connect to this MySQL server".解决办法如下: 方法/步骤 1 首先看报错窗口. 2 经查阅,错误原因是:本地IP(xxx.xxx.xxx.xxx)没有访问远程数据库的权限. 于是下面开启本地IP(xxx.xxx.xxx.xxx)对远程mysql数据库的访问权限. 3 首先远程连接进

如何解决Eclipse开发android程序的编译错误:com/android/dx/command/dexer/Main : Unsupported major.minor version 52.0?

近日,升级了android的开发工具,发现它在Eclipse上运行程序的时候报如下的错误: Errors occurred during the build.   Errors running builder 'Android Package Builder' on project 'EX04_03'.   com/android/dx/command/dexer/Main : Unsupported major.minor version 52.0 原因:个人电脑上装的JDK是1.7 解决办法

解决 java/lang/NoClassDefFoundError: java/lang/Object 错误

安装完JDK ,设定环境变量后出现这个错误: [[email protected] lib]# javacError occurred during initialization of VMjava/lang/NoClassDefFoundError: java/lang/Object [[email protected] lib]# javaError occurred during initialization of VMjava/lang/NoClassDefFoundError: jav