JavaScript之事件
- 事件
-
事件流
- 事件冒泡
- 事件捕获
- DOM事件流
-
事件处理程序
- HTML事件处理程序
- DOM3级实例
- DOM0级事件处理程序
- DOM2级事件处理程序/IE事件处理程序
- DOM3级事件处理程序
-
事件对象
- DOM中的事件对象
- IE中的事件对象
1. 事件
JavaScript和HTML的交互是通过事件完成的。事件,就是文档或者浏览器窗口中发生的一些特定的交互瞬间(click,hover等)。
2. 事件流
事件流是指从页面接受事件的顺序。包括IE提出的事件冒泡流以及Netscape 提出的事件捕获流。
2.1 事件冒泡(自里向外)
IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)。
实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body id="body">
<div id="div1">
<div id="div2">
<button id="div3">div3</button>
</div>
</div>
</body>
<script>
let div1 = document.getElementById("div1");
let div2 = document.getElementById("div2");
let div3 = document.getElementById("div3");
let body = document.body;
div1.onclick = function () {
console.log(this.id);
}
div2.onclick = function () {
console.log(this.id);
}
div3.onclick = function () {
console.log(this.id);
}
body.onclick = function () {
console.log(this.id);
}
</script>
</html>
结果:
ps:
所有的现代浏览器都支持事件冒泡,但在具体实现上有一些差别。IE5.5及更早版本中的事件冒泡会跳过< html >元素(从< body > 直接跳到documen)。IE9, Firefox,Chrome和Safari则将事件一直冒泡到window对象。
2.2 事件捕获(自外向里)
Netscape Communicator团队提出的另一种事件流叫做事件捕获(event capturing)。事件捕获的思想是不太具体的节点应该更早接受到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于再事件到达预定目标之前捕获它。
实例:
body.addEventListener("click",function(e){
console.log("body 捕获事件");
},true);
div3.addEventListener("click",function(e){
console.log("div3 捕获事件");
},true);
div2.addEventListener("click",function(e){
console.log("div2 捕获事件");
},true);
div1.addEventListener("click",function(e){
console.log("div1 捕获事件");
},true);
结果:
2.3 DOM事件流
"DOM2级事件"规定的事件流包括三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。
实例:
let div1 = document.getElementById("div1");
let div2 = document.getElementById("div2");
let div3 = document.getElementById("div3");
let body = document.body;
body.addEventListener("click",function(e){
console.log("body 捕获事件");
},true);
div3.addEventListener("click",function(e){
console.log("div3 捕获事件");
},true);
div2.addEventListener("click",function(e){
console.log("div2 捕获事件");
},true);
div1.addEventListener("click",function(e){
console.log("div1 捕获事件");
},true);
body.addEventListener("click",function(e){
console.log("body 冒泡事件");
},false);
div3.addEventListener("click",function(e){
console.log("div3 冒泡事件");
},false);
div2.addEventListener("click",function(e){
console.log("div2 冒泡事件");
},false);
div1.addEventListener("click",function(e){
console.log("div1 冒泡事件");
},false);
结果:
3. 事件处理程序
事件就是用户或者浏览器自身执行的某种动作。如click,load,和mouseover,都是事件的名字。而响应某个事件的函数就叫做事件处理程序(或事件侦听器)。大多数情况下,将事件处理程序添加到事件冒泡阶段,这样可以最大限度的兼容各种浏览器。
3.1 HTML事件处理程序
<input type="button" value="click me" onclick="console.log(event.target)" />
3.2 DOM0级事件处理程序
<!-- html -->
<input type="button" id="btn1" value="btn1-value" />
// js
let btn1 = document.getElementById('btn1');
btn1.onclick = function() {
alert(this.id);
}
this指向btn1
删除:
btn.onclick = null;
缺点:
指定多个只会执行最后一个
btn1.onclick = function() {
alert("1");
}
btn1.onclick = function() {
alert("2");
}
btn1.onclick = function() {
alert("3");
}
btn1.onclick = function() {
alert("4");
}
// 4
3.3 DOM2级事件处理程序
"DOM2级事件"定义了两个方法,用于处理制定和删除两个事件处理程序的操作:addEventListener() 和 removeEventListener()。所有的dom节点都包裹这两个方法。并且它们都接受三个参数:要处理的程序名,作为事件处理程序的函数和一个布尔值(调用事件处理程序的时间:true事件捕获时调用,false事件冒泡时)。
let btn1 = document.getElementById('btn1');
btn1.addEventListener("click", function() {
alert("click me");
}, false)
**ps: **
removeEventListener()无法移除匿名函数。
3.4 IE事件处理程序
IE实现了与DOM中类似的两个方法:attachEvent() 和 detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称和事件处理程序函数。由于ie8及之前的版本只支持冒泡,所以attachevent()添加的事件会被添加到事件冒泡阶段。
let handler = function() {
alert("clicked");
}
btn1.attachEvent("onclick", handler);
btn1.detachEvent("onclick", handler);
ps:
removeEventListener()无法移除匿名函数。
4. 事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息
4.1 DOM中的事件对象
兼容DOM的浏览器会将一个event对象传入到事件处理器程序中(DOM0级和DOM2级都可以)
btn1.addEventListener("click", function() {
console.log(event)
}, false)
常用event属性:
currentTarget:等于this,事件绑定的对象
target:具体触发事件的对象
preventDefault:阻止默认行为触发,如a标签的跳转
stopPropagation:阻止事件流继续,事件冒泡或者事件捕获停止于当前节点
4.2 IE中的事件对象
与访问DOM中的event对象不同,要访问IE中的event对象有几种不同的方式,取决于制定事件处理程序的方法。
- 使用DOM0级方法添加事件处理程序时,event对象作为window的一个属性存在。
btn1.onclick = function() { let event = window.event; console.log(event); }
- 使用attachEvent()添加的,那么就会有一个event对象传入参数中
btn1.attachEvent('onclick', function() { let event = window.event; console.log(event); })