天天看点

javascript——事件对比分析

事件流

事件流分为冒泡和捕获。

冒泡:即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。IE事件流就叫做事件冒泡
捕获:事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。

"DOM2级事件"规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

事件有哪些,之间的区别是什么呢?

事件 添加事件 删除事件 绑定多个事件 兼容
HTML事件 在html元素上以事件名加上前缀on作为属性,后面跟上javascript代码 ×
DOM0事件 将一个函数赋值给一个事件处理程序属性。简单跨浏览器,至今仍然为所有现代浏览器所支持 置为null ×
DOM2事件 addEventListener(type, handler, option) removeEventListener(type, handler, option) IE9及以上
IE事件 attachEvent(type, handler) detachEvent(type, handler) IE Opera

详细介绍

(1)HTML事件

    添加事件

<input type="button" value="Click Me" onclick="alert('Clicked')" />
           

直接在html元素上,通过on加上事件名作为html元素属性,后面更上javascript代码,也可以是一个函数执行方式。event对象可以直接使用

缺点:

  • 时差问题,用户可能会在HTML 元素一出现在页面上就触发相应的事件,这时候事件处理程序可能不具备执行条件,就会引发错误
  • 作用域链在不同浏览器中会导致不同结果
  • HTML和Javascript代码紧密耦合。这也是我们不用这个方法的原因。

(2)DOM0事件

    添加事件

var btn = document.getElementById("myBtn"); 
btn.onclick = function(){ 
 alert("Clicked"); 
};
           

 删除事件

btn.onclick = null; //删除事件处理程序
           

(3)DOM2事件

添加事件

var btn = document.getElementById("myBtn"); 
btn.addEventListener("click", function(){ 
 alert(this.id); 
}, false);
           

 接收三个参数:事件名,事件处理函数,布尔值。布尔值默认为false表示冒泡,true表示捕获。

删除事件

var handler = function(){ 
 alert(this.id); 
}; 
btn.addEventListener("click", handler, false); 
//这里省略了其他代码
btn.removeEventListener("click", handler, false); //有效!
           

上面通过匿名函数作为事件处理程序,要删除就不行的。因为函数是对象,长的一样不是同一个对象,所以需要使用函数表达式,最后将这个名字传入removeEventListener。

事件处理函数中,this表示当前目标元素。

兼容:IE9、Firefox、Safari、Chrome 和 Opera 支持 DOM2 级事件处理程序

(4)IE事件

添加事件

var btn = document.getElementById("myBtn"); 
btn.attachEvent("onclick", function(){ 
 alert("Clicked"); 
});
           

其他都是一样和DOM2级事件,就是名字attachEvent对应addEventListener,还有事件名字前加上on。

删除对应方法detachEvent,这里就不贴代码了。

为什么IE添加删除只有两个参数,因为 IE8 及更早版本只支持事件冒泡。

事件处理函数中,this表示window,因为在全局作用域中运行。

兼容:支持 IE 事件处理程序的浏览器有 IE 和 Opera。

IE和DOM2级事件都可以绑定多个事件处理程序。但是执行循序:DOM2是顺序执行,IE事件处理程序是IE8及以下反着来,IE9及以上是顺序执行。

(5)添加删除之跨浏览器

let EventUtil = { 
 
 addHandler: function(element, type, handler){ 
     if (element.addEventListener){ 
         element.addEventListener(type, handler, false); 
     } else if (element.attachEvent){ 
         element.attachEvent("on" + type, handler); 
     } else { 
         element["on" + type] = handler; 
     } 
 }, 
 removeHandler: function(element, type, handler){ 
     if (element.removeEventListener){ 
         element.removeEventListener(type, handler, false); 
     } else if (element.detachEvent){ 
         element.detachEvent("on" + type, handler); 
     } else { 
         element["on" + type] = null; 
     } 
 } 
};
           

参考资料

《javascript高级程序设计(第3版)》(万丈高楼平地起,基础很重要,就像说相声也一样)

继续阅读