16. 事件委托、代理
DOM事件流分为三个阶段: 事件捕获阶段、处于目标阶段、事件冒泡阶段
addEventListener
addEventListener
有三个参数
- 第一个参数为需要绑定的事件
- 第二个参数为触发事件后执行的回调函数
- 第三个参数为在何阶段触发事件处理函数(true为事件捕获阶段、false为事件冒泡阶段,默认为false)
事件冒泡
当一个元素接收到事件以后,会把他接收到的事件传给自己的父级,一直到window(传递的仅仅是事件,并不传递绑定的函数)
给三个盒子依次绑定点击事件,点击盒子时,会依次触发父级元素的点击事件
js
let small = document.querySelector('.small')
let center = document.querySelector('.center')
let big = document.querySelector('.big')
small.addEventListener('click', function(e) {
console.log('small')
})
center.addEventListener('click', function(e) {
console.log('center')
})
big.addEventListener('click', function(e) {
console.log('big')
})
点击small
会触发small、center、big
点击center
会触发center、big
点击big
会触发big
- 去掉父元素(
big
和center
),点击small
只会触发small
- 去掉子元素(
small
),点击small
会触发center
和big
阻止事件冒泡,使用event.stopPropagation()
js
small.addEventListener('click', (e)=>{
e.stopPropagation();
console.log('small')
})
事件捕获
当鼠标点击或者触发dom事件时(触发事件的dom元素叫事件源),浏览器会从根节点 -> 事件源进行事件传播。
捕获与冒泡类似,就是传播方向不同。
js
big.addEventListener('click', ()=>{
console.log('big --- 捕获')
}, true)
center.addEventListener('click', ()=>{
console.log('center --- 捕获')
}, true)
small.addEventListener('click', ()=>{
console.log('small --- 捕获')
}, true)
big.addEventListener('click', ()=>{
console.log('big --- 冒泡')
}, false)
center.addEventListener('click', ()=>{
console.log('center --- 冒泡')
}, false)
small.addEventListener('click', ()=>{
console.log('small --- 冒泡')
}, false)
点击small
,依次触发
big -- 捕获
center -- 捕获
small -- 捕获
small -- 冒泡
center -- 冒泡
big -- 冒泡
事件委托(代理)
利用事件冒泡,将子元素的事件都绑定到父元素上,如果子元素阻止了事件冒泡,那么委托就无法实现。
主要原理是:将事件监听器设置在父节点上,利用冒泡原理影响设置每个子节点
主要用途:防止大量事件注册
html
<ul class='ulList'>
<li class='listItem'>1</li>
<li class='listItem'>2</li>
<li class='listItem'>3</li>
<li class='listItem'>4</li>
</ul>
js
const ul = document.querySelector('.ulList')
const li = document.querySelectorAll('.listItem')
// 不使用事件代理
li.forEach((lis) => {
lis.onClick = (e) => {
console.log(e.innerHtml)
}
})
// 使用事件代理,用父元素去捕捉冒泡
ul.addEventListener('click',(e)=>{
console.log(e.target.innerHTML)
})