说下事件模型
1. 什么是事件和事件流
javascript 是事件驱动型语言。当用户在网页中进行某种操作时,就产生了一个“事件”(Event)。当事件发生时,JavaScript 可以对之做出响应,具体如何响应某个事件由编写的事件处理函数完成。
事件流描述的就是从页面中接收事件的顺序,早期 IE 和 Netscape 提出了完全相反的事件流概念,IE 事件流是事件冒泡,而Netscape的事件流就是事件捕获。
2. 冒泡和捕获的区别,触发顺序
IE 提出的事件流是事件冒泡,即从下至上,从目标触发的元素逐级向上传播,直到 window 对象。
Netscape 的事件流就是事件捕获,即从 document 逐级向下传播到目标元素。由于 IE 低版本浏览器不支持,所以很少使用事件捕获。
后来 ECMAScript 在 DOM2 中对事件流进行了进一步规范,基本上就是上述二者的结合。
DOM2级事件规定的事件流包括三个阶段: (1)事件捕获阶段 (2)处于目标阶段 (3)事件冒泡阶段
3. 冒泡和捕获的使用方式、应用场景
//给body侦听点击事件,冒泡阶段执行
document.body.addEventListener("click", clickHandler);
//给body侦听点击事件,捕获阶段执行
document.body.addEventListener("click", clickHandler,true);
//给body侦听点击事件,只执行一次
document.body.addEventListener("click", clickHandler,{once:true});
// 事件侦听添加(注册事件)占有内存的,所以当删除对象时,一定要将对象上的侦听事件移除
document.body.removeEventListener("click", clickHandler);
onclick支持IE低版本,addEventListener不支持IE8一下,低版本的IE使用 attachEvent 进行事件侦听;使用 detachEvent 移除事件侦听。
4. 如何阻止冒泡
e.stopPropagation();
e.cancelBubble=true // IE8及以下浏览器
5. 什么是事件委托
添加事件侦听(注册事件)占有内存的,尽量减少事件侦听的数量,将子元素的事件委托给父元素来执行,叫做事件委托。
事件委托利用的就是冒泡的原理。
当删除对象时,一定要将对象上的侦听事件移除,否则会造成内存泄露。
如果有多个DOM节点需要监听事件的情况下,给每个DOM绑定监听函数,会极大的影响页面的性能,因此我们通过事件委托来进行优化。
dom0、dom2、dom3事件: https://www.jianshu.com/p/3acdf5f71d5b