事件代理、冒泡、捕获(手写系列)

387 阅读2分钟

代理和冒泡

  1. 事件代理(委托):事件委托就是利用事件冒泡的过程中会上传到父节点,并且父节点可以通过时间对象获取到目标节点,因此可以把子节点的监听函数定义在父节点,由父节点的监听函数统一处理多个子节点的事件。// e.stopPropagation()阻止事件冒泡
  2. 事件冒泡:在一个对象上触发事件,如果该对象没有绑定事件,就会向父级对象传播,由父级对象触发事件。 

事件委托作用

(1)支持为同一个DOM元素注册多个同类型事件

(2)可将事件分成事件捕获和事件冒泡机制

手写

<ul id="item-list">
	<li>item1</li>
	<li>item2</li>
	<li>item3</li>
	<li>item4</li>
</ul>

// 事件代理写法
window.onload = () =>{
    var items = document.querySelector('ul')
    items.onclick = (e) => {
        console.log(e.target.innerHTML)
    }
}

//事件捕获实现事件代理
var items = document.getElementById('item-list')
items.addEventListener('click', (e) => {
    console.log('捕获:click ',e.target.innerHTML)}, true
)

//事件冒泡实现事件代理
items.addEventListener('click', (e) => {
    console.log('冒泡:click ',e.target.innerHTML)}, false
)

事件流

事件流描述的是从页面中接收事件的顺序

我们将这种事件流向分为三个阶段:捕获阶段,目标阶段,冒泡阶段

  • 捕获阶段是指事件响应从最外层的Window开始,逐级向内层前进,直到具体事件目标元素。在捕获阶段,不会处理响应元素注册的冒泡事件。

  • 目标阶段指触发事件的最底层的元素,如上图中的。

  • 冒泡阶段与捕获阶段相反,事件的响应是从最底层开始一层一层往外传递到最外层的Window。

现在,我们就可以知道,DOM事件流的三个阶段是先捕获阶段,然后是目标阶段,最后才是冒泡阶段。我们时常面试所说的先捕获后冒泡也由此而来。事件代理就是利用事件冒泡或事件捕获的机制把一系列的内层元素事件绑定到外层元素。

注意:

  • JS代码只能执行捕获或者冒泡其中的一个阶段
  • onclick 和 attachEvent 只能得到冒泡阶段
  • addEventListener (type, listener[, useCapture]) 第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认就是false),表示在事件冒泡阶段电泳事件处理程序。
  • 在实际开发中,我们很少使用事件捕获(低版本ie不兼容),我们更关注事件冒泡
  • 有些事件是没有冒泡的,比如onblur、onfocus、onmouseover、onmouseleave
  • 虽然事件冒泡有时候会带来麻烦,但是有时候又会巧妙的做某些事情,我们后面讲解