Blog icon indicating copy to clipboard operation
Blog copied to clipboard

浏览器事件代理机制的原理是什么?

Open YvetteLau opened this issue 5 years ago • 4 comments

YvetteLau avatar Apr 21 '19 15:04 YvetteLau

在说浏览器事件代理机制原理之前,我们首先了解一下事件流的概念,早期浏览器,IE采用的是事件捕获事件流,而Netscape采用的则是事件捕获。"DOM2级事件"把事件流分为三个阶段,捕获阶段、目标阶段、冒泡阶段。现代浏览器也都遵循此规范。

那么事件代理是什么呢?

事件代理又称为事件委托,在祖先级DOM元素绑定一个事件,当触发子孙级DOM元素的事件时,利用事件冒泡的原理来触发绑定在祖先级DOM的事件。因为事件会从目标元素一层层冒泡至document对象。

为什么要事件代理?

  1. 添加到页面上的事件数量会影响页面的运行性能,如果添加的事件过多,会导致网页的性能下降。采用事件代理的方式,可以大大减少注册事件的个数。

  2. 事件代理的当时,某个子孙元素是动态增加的,不需要再次对其进行事件绑定。

  3. 不用担心某个注册了事件的DOM元素被移除后,可能无法回收其事件处理程序,我们只要把事件处理程序委托给更高层级的元素,就可以避免此问题。

如将页面中的所有click事件都代理到document上:

addEventListener 接受3个参数,分别是要处理的事件名、处理事件程序的函数和一个布尔值。布尔值默认为false。表示冒泡阶段调用事件处理程序,若设置为true,表示在捕获阶段调用事件处理程序。

document.addEventListener('click', function (e) {
    console.log(e.target);
    /**
    * 捕获阶段调用调用事件处理程序,eventPhase是 1; 
    * 处于目标,eventPhase是2 
    * 冒泡阶段调用事件处理程序,eventPhase是 1;
    */ 
    console.log(e.eventPhase);
    
});

YvetteLau avatar Apr 22 '19 03:04 YvetteLau

第三个参数也接收一个对象 {capture:false ,once:true ,passive:true}

capture:该类型的事件冒泡阶段触发, once:添加之后最多只调用一次, passive:表示永远不会调用 preventDefault()。

并且不同的事件处理程序的 passive 的默认是不一样的。 在移动端的 touchmove 事件中 passive 值默认为 true,如果要在移动端中阻止滚动的话,要手动将 passive 设置为 false。

beginnerJq avatar Apr 23 '19 06:04 beginnerJq

楼上正解,附上MDN-addEventListener链接地址

fanerge avatar Apr 30 '19 01:04 fanerge

第三个参数也接收一个对象 {capture:false ,once:true ,passive:true}

capture:该类型的事件冒泡阶段触发, once:添加之后最多只调用一次, passive:表示永远不会调用 preventDefault()。

并且不同的事件处理程序的 passive 的默认是不一样的。 在移动端的 touchmove 事件中 passive 值默认为 true,如果要在移动端中阻止滚动的话,要手动将 passive 设置为 false。

稍后更正一下~非常感谢~

YvetteLau avatar Apr 30 '19 01:04 YvetteLau