DOM 事件模型与事件委托

324 阅读2分钟

一、捕获和冒泡

<div class="爷爷">
    <div class="爸爸">
      <div class="儿子">
        文字
      </div>
    </div>
</div>

即 .爷爷>.爸爸>.儿子,分别添加事件监听 fnYe / fnBa / fnEr

那么如果我点击文字,三个事件监听函数的调用顺序是怎样的呢,

如果按 爷爷=>爸爸=>儿子 的调用顺序,这就是捕获,

如果按 儿子=>爸爸=>爷爷 的调用顺序,这就是冒泡,

亦即从外向内找监听函数,叫事件捕获

从内向外找监听函数,叫事件冒泡

另外W3C 事件模型是先捕获(先爸爸 => 儿子),再冒泡(先儿子 => 爸爸)

二、事件绑定API

xxx.addEventListener('click',fn,bool)

  • 如果bool不传或者为falsy,就让fn走冒泡,即当浏览器在冒泡阶段发现xxxfn监听函数,就会调用fn,并提供事件信息。
  • 如果booltrue,就让fn走捕获。

三、事件委托

由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件委托

优点:

1. 省监听数,即省内存

如你要给100个按钮添加点击事件,就可以监听这100个按钮的父元素,等冒泡的时候判断target是否是这100个按钮中的一个。

2. 可以监听动态元素

如你要监听一个不存在的元素的点击事件,就可以监听父元素,等点击的时候看看是不是你要监听的元素即可。

var ul = document.querySelector('ul');

ul.addEventListener('click', function (event) {
  if (event.target.tagName.toLowerCase() === 'li') {
    // some code
  }
})

上面代码中,click事件的监听函数定义在<ul>节点,但是实际上,它处理的是子节点<li>click事件。