关于原生js中ie的attacheEvent事件用匿名函数改变this指向后,不能用detachEvent删除绑定事件的解决办法?

2017-11-28 22:51:31 4,008 views

封装ie事件处理程序时
ele.attachEvent('on' + type, fn); *这里会出现2中情况就是ie中attachEvent事件在ie9以下指向为window, * 可以有3中解决办法

 1:用匿名函数

用匿名函数来代替fn,function() { fn.call(ele);//改变this的指向,现在this指向当前元素,但是不能删除绑定事件 }

2.如果不改变回调函数fn,在使用的时候改变this指向也可以

var hand=function(event) {
var event=base.getEvent(event);
var _this=event.srcElement||event.target;
};
base.addHandler(box, "click", hand); //会废掉原来的this,

3:重写方法,不用attachEvent和detachEvent

<a id="xc">点击</a>
<script type="text/javascript">
        /*
         * 添加事件处理程序
         * @param object object 要添加事件处理程序的元素
         * @param string type 事件名称,如click
         * @param function handler 事件处理程序,可以直接以匿名函数的形式给定,或者给一个已经定义的函数名。匿名函数方式给定的事件处理程序在IE6 IE7 IE8中可以移除,在标准浏览器中无法移除。
         * @param boolean remove 是否是移除的事件,本参数是为简化下面的removeEvent函数而写的,对添加事件处理程序不起任何作用
        */
        function addEvent(object,type,handler,remove){
                if(typeof object!='object'||typeof handler!='function') return;
                try{
                        object[remove?'removeEventListener':'addEventListener'](type,handler,false);
                }catch(e){
                        var xc='_'+type;
                        object[xc]=object[xc]||[];
                        if(remove){
                                var l=object[xc].length;
                                for(var i=0;i<l;i++){
                                        if(object[xc][i].toString()===handler.toString()) object[xc].splice(i,1);
                                }
                        }else{
                                var l=object[xc].length;
                                var exists=false;
                                for(var i=0;i<l;i++){
                                        if(object[xc][i].toString()===handler.toString()) exists=true;
                                }
                                if(!exists) object[xc].push(handler);
                        }
                        object['on'+type]=function(){
                                var l=object[xc].length;
                                for(var i=0;i<l;i++){
                                        object[xc][i].apply(object,arguments);
                                }
                        }
                }
        }
        /*
         * 移除事件处理程序
        */
        function removeEvent(object,type,handler){
                addEvent(object,type,handler,true);
        }
</script>
<script type="text/javascript">
        function handler(){
                alert(this.innerHTML);
        }
        var object=document.getElementById('xc');
        addEvent(object,'click',handler);
        //如果要测试绑定事件,请先删除下面这一行。
        removeEvent(object,'click',handler);

 
 
1,2 两种方法各有取舍。
以下是测试案例,带删除事件处理程序,可以分别用chrome,firefox,ie7以上来测试。
解决ie9以下this指向问题,让其"this"指向当前元素。
以下是封装的测试代码

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <div id="box" style="width: 100px; height: 100px;background: blue;"></div>
    <script type="text/javascript">
    ;
!(function(window, document) {
  function Base() {}
  /*获取Id*/
  Base.prototype = {
    getDom: function(id) {
      return document.getElementById(id);
    },
    /*添加事件处理程序*/
    addHandler: function(ele, type, fn) { //handler什么操作
      if(ele.addEventListener) {
        ele.addEventListener(type, fn, false); //DOM2级事件处理程序
      } else if(ele.attachEvent) {
        ele.attachEvent('on' + type, fn); //IE事件处理程序
      } else {
        ele['on' + type] = fn;
      }
    },
    /*删除事件处理程序*/
    removeHandler: function(ele, type, fn) { //handler什么操作
      if(ele.removeEventListener) {
        ele.removeEventListener(type, fn, false); //DOM2级判断
      } else if(ele.detachEvent) {
        ele.detachEvent('on' + type, fn);
      } else {
        ele['on' + type] = null;
      }
    },
    /*start 事件对象的相关属*/
    getEvent: function(event) { //怎么来获取兼容所有浏览器的事件对象
      return event ? event : window.event;
      //IE8以前的要用window.event
    }
    /*		--------------------------*/
  }
  window.Base = Base;
})(window, document);
    </script>
    <script type="text/javascript">
      var base = new Base();
      var box=base.getDom("box");
      var hand=function(event) {
         var event=base.getEvent(event);
        var _this=event.srcElement||event.target;
        alert(_this.nodeName);
      };
      base.addHandler(box, "click", hand);
      //base.removeHandler(box,"click",hand);  //删除绑定事件
    </script>
  </body>
</html>

第三种方法传送   https://www.51-n.com/t-4203-1-1.html

1

分享到微信朋友圈

打开微信,点击底部的“发现”,
使用“扫一扫”即可将网页分享至朋友圈。