事件冒泡和事件捕获
# 事件流:事件发生顺序
<div id="outer">
<div id="inner">Click me!</div>
</div>
如果outer和inner都有click事件,那么点击inner,哪个事件会被触发?
# 事件冒泡:
事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。 也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。
div(inner) -> div(outer) -> body -> html -> document
# 事件捕获:
与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。 上面的例子在事件捕获的概念下发生click事件的顺序应该是
document -> html -> body -> div(outer) -> div(inner)
# addEventListener的使用
element.addEventListener(event, function, useCapture) - useCapture: - true - 事件句柄在捕获阶段执行(即在事件捕获阶段调用处理函数) - false- false- 默认。事件句柄在冒泡阶段执行(即表示在事件冒泡的阶段调用事件处理函数)
# 阻止事件冒泡:
给子级加 event.stopPropagation( ):
$("#div1").mousedown(function(e){ var e=event||window.event; event.stopPropagation(); });
在事件处理函数中返回 false
$("#div1").mousedown(function(event){ var e=e||window.event; return false; });
注:但是这两种方式是有区别的。return false 不仅阻止了事件往上冒泡,而且阻止了事件本身(默认事件)。 event.stopPropagation()则只阻止事件往上冒泡,不阻止事件本身。
- 在回调函数中利用event.target==event.currentTarget来进行判断,在成立的时候处理逻辑
# 事件委托/事件代理:
由于事件会在冒泡阶段向上传播到父节点,可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。
一般尽可能使用事件冒泡,因为相对于事件委托,兼容性更好。
比如给ul标签下的一万个li标签绑定监听处理点击li的逻辑: 可以在ul上绑定监听,每次点击li的时候都会在ul监听到,然后通过判断event.target来判断点击来源,处理逻辑。