事件捕获/冒泡/委托

269 阅读2分钟

事件捕获/冒泡

  • 有一个三层嵌套元素,爷-父-子。 点击子元素也相当于点击了父和爷元素

渊源

  • 点击之后,事件的发生顺序是爷-父-子还是子-父-爷。网景公司和微软观点不一,最后W3C和稀泥,产生如下的观点
  1. 网景公司:

    爷-父-子 称为事件捕获

  2. 微软:

    子-父-爷 称为事件冒泡

添加事件

div.attachEvent('onclick', fn) // 冒泡  IE
div.addEventListener('click', fn) // 捕获 网景
div.addEventListener('click', fn, bool) // W3C bool默认为false即冒泡, 如果为true则是捕获

target VS currentTarget

  • 区别
e.target // 用户操作的元素
e.currentTarget // 程序员监听的元素

// 例子
div>span{文字} , 用户点击文字
e.target 是span
e.currentTarget 是div

取消冒泡

e.stopPropagation()
  • 有些事件是不能取消的

事件委托

概念

  • 实质上就是在子元素不方便监听的情况下,监听父元素,比如一开始子元素还没有被造出来,或者子元素太多,就监听父元素来代替监听子元素
  • 装逼答法: 事件委托,通俗地来讲,就是把一个元素响应事件(click、keydown......)的函数委托到另一个元素; 一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。

代码实现

<ul id="list">
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
  ......
  <li>item n</li>
</ul>
// ...... 代表中间还有未知数个 li
// 给父层元素绑定事件
document.getElementById('list').addEventListener('click', function (e) {
  // 兼容性处理
  var event = e || window.event;
  var target = event.target;
  // 判断是否匹配目标元素
  if (target.nodeName.toLocaleLowerCase === 'li') {
    console.log('the content is: ', target.innerHTML);
  }
});