简要理解注册事件的兼容性处理和问题分析
在平常使用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真坑);

浙公网安备 33010602011771号