事件进阶
事件监听器
在 JavaScript 中,如果要给元素添加一个事件,可采用以下两种方式:
- 事件处理器
- 事件监听器
如果我们要给元素添加一个事件,一般会通过操作 HTML 属性的方式来实现,这种方式其实也叫作“事件处理器”。
缺点:事件处理器不能为一个元素添加多个相同事件。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick = function () {
alert("第 1 次");
};
oBtn.onclick = function () {
alert("第 2 次");
};
oBtn.onclick = function () {
alert("第 3 次");
};
};
</script>
</head>
<body>
<input id="btn" type="button" value="按钮" />
</body>
</html>
在这个例子中,我们一开始的目的是给按钮添加 3 次 onclick 事件,但 JavaScript 最终只会执行最后一次 onclick。可以看出,事件处理器不能为一个元素添加多个相同事件。
疑问
第一次、第二次未执行,只执行了最后一次?还是第一次、第二次也已执行,但被第三次的执行结果所覆盖?
如果要为一个元素添加多个相同的事件,该如何实现呢?这就需要用到另外一种添加事件的方式了,那就是——事件监听器。
1.绑定事件
所谓的“事件监听器”,指的是使用 addEventListener()
方法为一个元素添加事件,我们又称之为“绑定事件”。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.addEventListener(
"click",
function () {
alert("第 1 次");
},
false
);
oBtn.addEventListener(
"click",
function () {
alert("第 2 次");
},
false
);
oBtn.addEventListener(
"click",
function () {
alert("第 3 次");
},
false
);
};
</script>
</head>
<body>
<input id="btn" type="button" value="按钮" />
</body>
</html>
当我们点击按钮后,浏览器会 依次 弹出 3 个对话框。也就是说,我们可以使用“事件监听器”这种方式来为同一个元素添加多个相同的事件,而这一点是事件处理器做不到的。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
// 第 1 次调用 window.onload
window.onload = function () {
var oBtn1 = document.getElementById("btn1");
oBtn1.onclick = function () {
alert("第 1 次");
};
};
// 第 2 次调用 window.onload
window.onload = function () {
var oBtn2 = document.getElementById("btn2");
oBtn2.onclick = function () {
alert("第 2 次");(
};
};
// 第 3 次调用 window.onload
window.onload = function () {
var oBtn3 = document.getElementById("btn3");
oBtn3.onclick = function () {
alert("第 3 次");
};
};
</script>
</head>
<body>
<input id="btn1" type="button" value="按钮 1" /><br />
<input id="btn2" type="button" value="按钮 2" /><br />
<input id="btn3" type="button" value="按钮 3" />
</body>
</html>
在实际开发中,我们有可能会多次使用 window.onload,但是会发现 JavaScript 只执行最后一次 window.onload。为了解决这个问题,我们可以使用 addEventListener()
来实现。在这个例子中,我们只需要将每一个 window.onload 改为以下代码即可。
window.addEventListener("load", function () {……}, false);
- 事件监听器,可以为同一个元素添加多个相同的事件
obj.addEventListener(type, fn, false)
- type 是个 string,事件类型,比如 click,不需要加 on
- fn 是个函数名,或者是个匿名函数
- false 表示事件冒泡阶段调用
ogj.removeEventListener(type, fn, false)
,解绑,fn 一定需要是函数名,不能是匿名函数
- 在实际开发中,我们有可能会多次使用 window.onload,但是会发现 JavaScript 只执行最后一次 window.onload。为了解决这个问题,我们可以使用
addEventListener()
来实现window.addEventListener("load", fn, false)
;- 或者用自定义的
addLoadEvent()
函数
event 对象
当一个事件发生的时候,这个事件有关的详细信息都会临时保存到一个指定的地方,这个地方就是 event 对象。
在 JavaScript 中,我们可以通过 event 对象来获取一个事件的详细信息。
属性 | 说明 |
---|---|
type | 事件类型 |
keyCode | 键码值 |
shiftKey | 是否按下 Shift 键 |
ctrlKey | 是否按下 Ctrl 键 |
altKey | 是否按下 Alt 键 |
- 在 JavaScript 中,我们可以使用
event.type
来获取事件的类型
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick = function (e) {
alert(e.type);
};
};
</script>
</head>
<body>
<input id="btn" type="button" value="按钮" />
</body>
</html>
DANGER
想当然地以为,当鼠标点击按钮时,跳出的菜单文字会出现 button,结果出现的却是 click 。
- 在 JavaScript 中,如果我们想要获取键盘中的键对应的键码,可以使用
event.keyCode
- 如果是 Shift 键、Ctrl 键和 Alt 键,我们不需要通过 keyCode 属性来获取,而可以通过 shiftKey、ctrlKey 和 altKey 属性来获取
this
在事件操作中,可以这样理解:哪个 DOM 对象(元素节点)调用了 this 所在的函数,那么 this 指向的就是哪个 DOM 对象。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
window.onload = function () {
var oDiv = document.getElementsByTagName("div")[0];
oDiv.onclick = function () {
this.style.color = "hotpink";
};
};
</script>
</head>
<body>
<div>马拉松派,我们都在努力地成为长期主义者!</div>
</body>
</html>
那么,为什么用 oLi[i] 不正确,而必须要用 this 呢?其实这就是典型的闭包问题。对于闭包,我们在 JavaScript 进阶中再详细介绍。在事件函数中,如果想要使用当前的元素节点,我们应该尽量使用 this 来代替 oBtn、oLi[i] 等写法。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script>
window.onload = function () {
var oUl = document.getElementById("list");
var oLi = oUl.getElementsByTagName("li");
for (var i = 0; i < oLi.length; i++) {
oLi[i].onclick = function () {
// oLi[i].style.color = "hotpink";
this.style.color = "hotpink";
};
}
};
</script>
</head>
<body>
<ul id="list">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</body>
</html>