前端常见知识点(四)

前端常见知识点(四)

三月 08, 2019

事件

IE 的事件流叫做「事件冒泡」,是指事件开始的时候是由最具体的元素(文档中嵌套层次最深的那个节点),或者说,是距离事件发生的最近的节点接受,然后逐级向上传播到较为不具体的节点(document)。

而 Netscape (网景)团队提出的另外一种事件流叫做「事件捕获」,与事件冒泡刚好相反,事件捕获的思想是不太具体的节点应该更先接收到事件,最具体的节点最后接收到事件。

DOM 事件流

「DOM 2 级事件」规定,事件流包括三个阶段:事件捕获事件处理事件冒泡阶段,并且在事件捕获的阶段,实际发生事件的节点不会接收到事件,事件从document<html>再到<body>后就停止了,之后在目标节点上发生,并在事件处理中被看成是冒泡阶段的一部分,之后在冒泡阶段中,事件又传播回document

事件对象

事件对象event是一个 在触发 DOM 上的某个事件时产生的,包含所有与该事件有关的信息的 对象。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<body>
<div>
<button id="btn">BUTTON</button>
</div>
<script>
var btn = document.getElementById('btn')
btn.onclick = (event) => {
console.log(event)
}
</script>
</body>
</html>

点击按钮,然后在 Chrome 浏览器的控制台里我们就可以看到event对象的所有信息了。比如事件的类型event.typeclick),事件的目标(即导致事件产生的元素)event.targetbutton#btn)等。合理利用事件对象的这些属性帮助我们提升不少工作效率,例如使用target属性完成事件委托。

事件委托

在「红宝书」中有这么一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html>
<body>
<ul id="links">
<li id="goSomewhere">Go Somewhere</li>
<li id="doSomething">Do doSomething</li>
<li id="greet">Greet</li>
</ul>
<script>
var links = document.getElementById('links')
links.addEventListener('click', (event) => {
var target = event.target
switch (target.id) {
case 'goSomewhere':
location.href = 'anotherPage.html'
break
case 'doSomething':
document.title = 'The Title Changed'
break
case 'greet':
alert('Hello!')
break
}
})
</script>
</body>
</html>

在这个例子里,我们使用事件委托只为<ul>元素添加了一个onclick事件处理程序,由于事件冒泡的特点,<ul>就可以处理它的所有子节点<li>的事件,这样子,比取得每一个<li>元素并分别对齐添加事件要方便的多。

并且这种方式因为只取得了一个 DOM 元素,只添加了一个事件处理程序,所以占用的内存更少,所花的时间也更少。