JS DOM 事件流、事件冒泡
说说事件委托
当一个HTML元素触发一个事件时,该事件会在元素结点与根结点之间的路径传播。传播按顺序分为三个阶段: 捕获阶段 目标阶段 冒泡阶段,这个传播过程就是DOM事件流。
事件冒泡就是当一个HTML元素出发的一个事件时,它的祖先节点都会收到该事件。
- 通过设置addEventListener的第三个参数可以决定事件是否在捕获阶段触发。
通过 event.stopPropagation()可以阻止事件冒泡。
定义
DOM结构是一个树型结构,当一个HTML元素出发一个事件时,该事件会在元素结点与根节点之间的路径传播,路径所经过的节点都会收到该事件,这个传播过程可称为DOM事件流(DOM evnet flow)。
一个事件发生后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段。
第一阶段:从window对象传导到目标节点(上层传到底层),称为“捕获阶段”(capture phase)。
- 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
- 第三阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。
addEventListener 方法默认是让事件在冒泡阶段触发。 设置addEventListener 第三个参数 useCapture 的值为 true,就会让事件在捕获阶段触发。
停止传播:event.stopPropagation()
马上停止传播:event.stopImmediatePropagation()
有个特例,如果目标阶段的节点绑定了多个事件,它们不会区分捕获和冒泡,事件触发的顺序为代码执行的顺序。
而且event.stopPropagation()在目标阶段不会生效。如果目标阶段有 a、b、c 三个触发事件会按序执行,在 b 事件里设置event.stopPropagation()并不会影响 c 事件的触发。 但是如果在 b 事件里设置event.stopImmediatePropagation()后 ,事件触发到b之后就会停止触发后面的所有事件。事件委托
事件委托, 现实意义上讲是指将自己的事务嘱托他人代为处理。js中是 允许我们不必为某些特定的节点添加事件监听器,而是将事件监听器添加到(这些节点的)某个 parent节点上。利用事件冒泡,去找到匹配的子节点元素,然后做出相应的事件响应。是主要用来解决“事件处理程序过多”这个问题的。
Event 接口的只读属性 currentTarget 表示的,标识是当事件沿着 DOM 触发时事件的当前目标。它总是指向事件绑定的元素,而 Event.target 则是事件触发的元素。
好处:
1, 简化了初始化的过程,减少了多余的事件处理函数,进而节省了内存。提高性能。
2,新添加的元素还会有之前的事件。
缺点:第一,要求事件在IE中必须冒泡. 大多数的事件会冒泡,但是并不是所有的。对于其他的浏览器而言,捕获阶段也会同样适用。
- 第二,理论上委托会导致浏览器额外的加载,因为在容器内的任意一个地方事件的发生,都会运行事件处理函数,所以多数情况下事件处理函数都是在空循环(没有意义的动作),通常不是什么大不了的事儿。
- 第三 如果现在的dom 元素分为很多很多层,对于底层事件的委托,有可能在事件冒泡的过程中,中途被某个节点 终止冒泡了,这样事件就传递不到上层,则委托就会失败了。