持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情
事件和事件流
打开一个用户不能进行交互的网页,无论怎么点击网页都不会给出反应,要让网页和用户产生交互就会产生各种不同的事件。比如鼠标点击,鼠标滚动,键盘输入这些都是事件,在网页上发生的事件,触发之后并不会见到结束,而会触发事件流
某个元素被触发,这个元素并不是独立的,整个dom是一体的,单个元素事件触发以后会影响其他的元素,好比搬起石头砸自己的脚,分布在器官组织内的能感受到体外的刺激,转为神经冲动传到中枢再到大脑皮层,告诉你的大脑发生了疼痛,
这是因为一个事件产生的事件流通过冒泡的形式一层一层网上传输,网页也是如此,点击某个元素会以冒泡的形式一层一层往上传播,这个就叫事件冒泡
事件捕获与事件冒泡相反,它是从上往下的,在网页dom最顶部从上往下传播,我们点击的目标元素不会马上被触发,而是从顶部开始一直到下面再进行触发
DOM事件流
为了对事件流进行统一规范,将事件流归为三个阶段,1、事件捕获阶段,2、处于目标阶段,3.事件冒泡阶段
我们点击目标元素以后,先执行事件捕获阶段,到达目标阶段,最后事件冒泡阶段
事件处理
分别给三个嵌套的元素添加点击事件,点击最里面的元素可以看见事件全部都被触发了,再点击背景,只有最外层事件触发了。很明显这种形式属于事件冒泡,点击最里面的span元素触发目标元素事件,接着往上传播,点击最外层没有往下传播,不是事件捕获
<body onclick="console.log('body')">
<button onclick="console.log('button')">
<span onclick="console.log('span')">按钮</span>
</button>
</body>
那什么才是事件捕获呢,我们使用addEventListener事件监听,它的第三个参数是布尔值,由这个布尔值决定事件是以「捕获」还是「冒泡」机制执行,若不指定则默认为「冒泡」
<body>
<button>
<span>按钮</span>
</button>
</body>
<script>
let body=document.getElementsByTagName('body')[0]
let button=document.getElementsByTagName('button')[0]
let span=document.getElementsByTagName('span')[0]
function theName(){console.log('我是'+this.nodeName)}
body.addEventListener('click',theName,true)
button.addEventListener('click',theName,true)
span.addEventListener('click',theName,true)
</script>
若将button的addEventListener事件设为false,按照DOM的事件流,会先捕获然后才冒泡,浏览器打印的顺序就是body,span最后才是button了