简要理解注册事件的兼容性处理和问题分析

在平常使用js代码中事件是不可或缺的那么js中定义事件的方式有哪些呢?

01 addEventListener(事件类型,事件处理函数,useCapture);

02 attachEvent(事件类型,事件处理函数) 【用于ie 详细兼容性请参考MDN】

03 ele.on事件类型  = function{事件}

[01]useCapture:

细心的人可能会发现 addEventeListener中的参数貌似比attachEvent多了个欸;

那么useCapture是什么呢?

事件有三个阶段 1 捕获阶段(从外向里冒泡), 2 目标阶段 ,3 冒泡阶段(从里向外冒泡);

而useCapture是决定该事件是在捕获阶段调用还是在冒泡阶段调用;

  • true - 事件句柄在捕获阶段执行
  • false- false- 默认。事件句柄在冒泡阶段执行

我个input加了一个父节点,同时给他也加一个弹出事件。弹出 hello  子元素弹出 你好

现在是false 点击按钮 出现 你好 再出现 hello

改成true 点击按钮 先出现 hello  再出现 你好!

个人总结:false的话 就是事件冒泡了 从子元素到父元素

                    true的话   就是事件捕获 从父到子!

[02]注册事件的兼容性处理

ok我们通过[01]简要理解了事件冒泡和事件捕获等问题那么进入今日正题,如何处理注册事件的兼容性问题

 1 //事件有三阶段  1阶段 捕获阶段(从外向内)  2 阶段 目标阶段  3阶段 冒泡阶段(从里向外进行冒泡)
 2     //1.在注册事件的时候,判断浏览器的注册事件的方式,然后直接使用该方式进行注册事件
 3     //复用性太差
 4     //2.将注册事件的代码封装到一个函数中
 5     //每次调用该函数,都会进行浏览器能力检测
 6     //3.在函数中返回函数,让外部函数只执行一次,判断也就只会执行一次
 7     //使用函数内创建的函数返回给外界,就可以重复使用该函数,进行事件的注册
 8 
 9     var div = document.getElementById("div1");
10     if(div.addEventListener) {
11         div.addEventListener('click', function () {
12             alert(true);
13         })
14     }else if (div.attachEvent)  {
15         div.attachEvent('click', function () {
16             alert("222");
17         })
18     }else {
19         div.onclick  = function () {
20             alert(333);
21         }
22     }
23     //封装成函数 但是问题是每次都会进行执行
24     function registEvent(target,type,fuc) {
25         if(target.addEventListener) {
26             target.addEventListener(type,fuc);
27         }else if(target.attachEvent) {
28             target.attachEvent(type,fuc);
29         }
30         target['on'+type] = fuc;
31 
32     }

虽然我们封装了函数但是每次都会执行噻,于是我们再进行升级

[03]升级代码

 1   //1、注册的事件的处理函数中的,this指向不一致
 2     //使用addEventListener的方式注册的点击事件的回调函数中的this 指向target
 3     //但是使用attachEvent的方式注册点击事件的回调函数中的this 指向window
 4 
 5     //2、3种注册事件的方式中,回调函数内获取事件对象的方式也是不一致的
 6     //要让他们统一,
 7     //在第二种的事件注册方式(attachEvent)中,手动给handler传递window.event
 8     function createEventRegister() {
 9         if (window.addEventListener) {
10             return function (target,type,hander) {
11                 target.addEventListener(type,hander);
12             }
13         }else  if (window.attachEvent) {
14             return function (target,type,hander) {
15                 target.attachEvent(type,hander);
16             }
17         }else {
18             return function (target,type,hander) {
19                 target['on'+type] = hander;
20             }
21         }
22     }
23 
24     var registeEvent = createEventRegister();
25 
26         var div = document.getElementById("div1");
27         registeEvent(div,"click",function(){
28             console.log(e);//mouseEvent //事件的调用对象
29             console.log(this);// div   //事件的触发对象 所以this就是事件的触发对象
30             //this---->该事件的触发对象
31             alert("太阳天空照,花儿对我笑,小鸟说:完了");
32         });

通过升级代码我们又发现了一些新的问题:

01 我们使用addEventListener 的时候其this指向的是target (也就是事件触发对象 例如例子中的div)

02 我们使用attachEvent的时候其this指向的是window

这是为什么呢?

[04]:注册事件兼容性问题分析:

 1  var div = document.getElementById("dvd1");
 2 
 3     div.onclick = function (e) {
 4         //this === div
 5     }
 6     div.addEventListener("click", function (e) {//e是事件的调用对象 也就是MouseEvent
 7         //this === div
 8     })
 9     div.attachEvent("onclick", function () {
10         //window.event获取div
11         //this === window
12     })

代码一目明了,target[on+type]的方式和addEventListener的方式其在事件使用的时候this指向的都是事件触发对象

attachEvent的this之所以指向的是window 是因为在attachEvent调用的时候需要通过window中的event方法获取事件触发对象,所以该事件中的this自然指向了window

[05]总结:

(ie真坑);

posted @ 2018-04-14 17:55  Lay-Buddhist  阅读(135)  评论(0)    收藏  举报