浅聊一下
试想一下,我们有三个div,每个div上有一个点击事件,点击最大的div会输出app,点击中间的div会输出wrap,点击最小的div会输出box。那么当我们点击分别点击每一个图层时会输出什么呢?本篇文章将带大家来深入分析一下事件的触发过程...
事件的触发过程
捕获过程
事件触发的第一个过程是捕获过程,在window上往事件触发处传播,遇到注册的捕获事件会触发(从外往内传播)
- 点击app
点击app,会从window开始往里找,第一步就找到了app,于是输出app
- 点击wrap
点击wrap,会从window开始往里找,先找到app,再找到wrap,那么我们的输出结果应该是app->wrap 但是结果真的是这样吗?不是, 输出结果为wrap->app
为什么会发生这种情况呢??? 因为在监听器中除了点击事件,触发方法,还有一个可选的参数,参数为布尔值,默认为false
如果第三个参数为true,那么在捕获事件过程捕获到的事件就会触发,如果为false,也就是默认,那就是在冒泡过程触发,所以在这里我们在冒泡过程触发事件,先输出wrap再输出app
js
app.addEventListener('click',(e)=>{//绑定 注册 订阅
console.log('app');
e.stopImmediatePropagation()
},false)
- 点击box 根据上面两个例子,我们很容易就知道,这里输出顺序为box->wrap->app
那我们来看看什么是冒泡过程
冒泡过程
冒泡过程就是在我们找到目标子容器以后,再向父容器传递的一个过程,也就是捕获事件相反的方向, 从事件触发处往window上传播,遇到注册的冒泡事件会触发
f
event.stopPropagation() || e.stopImmediatePropagation()
如果我只想要我点击的那个容器触发,其他容器不触发,那应该怎么办呢?那么我们就得用到event.stopPropagation()或e.stopImmediatePropagation()了
这两个方法都是用来阻止默认事件的传播(用在冒泡就阻止冒泡,捕获就阻止捕获)
js
let box = document.getElementById('box')
box.addEventListener('mouseenter',(e)=>{
console.log('box');
// e.stopPropagation()//停止传播
e.stopImmediatePropagation()
})
此时,我们点击box,就只会打印box
那么这两个方法有什么区别呢?
js
let box = document.getElementById('box')
box.addEventListener('mouseenter',(e)=>{
console.log('box');
//阻止冒泡
// e.stopPropagation()//停止传播
e.stopImmediatePropagation()
})
box.addEventListener('click',()=>{
console.log('box2');
})
我们在上面的代码中给box添加了两个点击事件,当我们点击box时,会触发,如果我们使用stopImmediatePropagation()来阻止默认事件的传播,那么我们的监听器只有一个会被触发,也就是mouseenter事件,如果使用 stopPropagation()那么两个事件都会触发...
事件委托
借助冒泡机制,将原本要添加到多个子容器上的事件添加到父容器上
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul id="ul">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
</ul>
<script>
let lis = document.querySelectorAll('li')
lis.forEach((li)=>{
li.addEventListener('click',()=>{
console.log(li.innerText);
})
})
</script>
</body>
</html>
如果我们要在ul中的每个li上添加点击事件,按照传统方法,我们可以先获取到每个li,再遍历添加点击事件,但是这种方法属实有一点low了,我们使用在父容器上添加点击事件的方法
js
let ul = document.getElementById('ul')
ul.addEventListener('click',(e)=>{
console.log(e.target.innerText);
})
在 ul
元素上添加了点击事件监听器。当用户点击 ul
元素内部的任意一个子元素时,事件会冒泡到 ul
元素,并触发该监听器。
在监听器中,通过 e.target
可以获取到实际触发事件的元素。通过 e.target.innerText
可以获取到该元素的文本内容。
结尾
祝掘友们新年快乐!!!!!!!!!!