浅析DOM事件委托

172 阅读1分钟

事件委托

利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

冒泡过程的传播路径为由内到外,利用此特点,不直接将监听器绑定至目标元素,而是绑定在其祖先元素上,由此也可实现一个监听器监听多个元素。

使用场景

  1. 需要同时监听多个子元素
<div id="div1">
  <button>click 1</button>
  <button>click 2</button>
  <button>click 3</button>
  <button>click 4</button>
  <button>click 5</button>
</div>

<script>
div1.addEventListener('click', (e)=> { 
  //把目标元素赋给t
  const t = e.target
  // 判断是否匹配目标元素
  if (t.tagName.toLowerCase() === 'button') {
    console.log('button内容是:' + t.textContent);
  }
});
</script>

通过在父元素div上绑定监听器,实现对其所有子元素的监听,与为每一个子元素绑定监听器相比,节省了内存。

  1. 监听动态元素/不存在的元素
<div id="div1">
</div>
<script>
setTimeout(()=>{
  //div1里面延迟添加一个button
  const button = document.creatElement('button')
  button.textContent = 'click 1'
  div1.appendChild(button)
},1000)

  
div1.addEventListener('click',(e)=>{
const t=e.target
if (t.tagName.toLowerCase() ==='button'){
  console.log('button被click')
}
});  
</script>

元素不存在时无法为其绑定监听器,可以通过对其父元素绑定监听器来实现监听。

封装事件委托

<div id="div1">
</div>
<script>
setTimeout(()=>{
  const button = document.creatElement('button')
  button.textContent = 'click 1'
  div1.appendChild(button)
},1000) 

 on('click','#div1','button',()=>{
 console.log('button被点击了')
 })  
  
 function on(eventType, element, selector, fn){
   //判断element是否为元素
   if(!(element instanceof Element)){
    element = document.querySelector(element)
    //非元素则视为CSS选择器
   }
 element.addEventListener(eventType,(e)=>{
 const t = e.target
 //matches判断一个元素是否满足一个选择器
 if(t.matches(selector)){
    fn(e) //函数处理事件信息
 }
 })
 }
</script>