Skip to content

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

  • 去掉父元素(bigcenter),点击small只会触发small
  • 去掉子元素(small),点击small会触发centerbig

阻止事件冒泡,使用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)
 })

KESHAOYE-知识星球