事件流
事件流分为冒泡和捕获。
冒泡:即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。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版)》(万丈高楼平地起,基础很重要,就像说相声也一样)