一个事件的处理过程主要有三个阶段:捕获、目标、冒泡。
- 捕获阶段:当我们在 DOM 树的某个节点发生了一些操作(例如单击、鼠标移动上去),就会有一个事件发射过去。这个事件从 Window 发出,不断经过下级节点直到触发的目标节点。在到达目标节点之前的过程,就是捕获阶段(Capture Phase)。(所有经过的节点,都会触发这个事件。捕获阶段的任务就是建立这个事件传递路线,以便后面冒泡阶段顺着这条路线返回 Window。)
- 目标阶段:当事件不断的传递直到目标节点的时候,最终在目标节点上触发这个事件,就是目标阶段。
- 冒泡阶段:事件冒泡即事件开始时,由最具体的元素接收(也就是事件发生所在的节点),然后逐级传播到较为不具体的节点(我们平时用的事件绑定就是利用的事件冒泡的原理)
- 事件捕获: 事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。
- 事件冒泡:事件冒泡刚好相反,是从触发事件的那个节点一直到document,是自下而上的去触发事件。
- 事件委托:利用了事件冒泡的原理,在下方通过实例讲解
- 阻止事件委托和冒泡:在事件函数中执行event.stopPropagation()
实例讲解:
<div id="parent">
<div id="child" class="child"></div>
</div>
<script type="text/javascript">
document.getElementById("parent").addEventListener("click",function(e){
console.log("parent事件被触发,"+this.id);
});
document.getElementById("child").addEventListener("click",function(e){
console.log("child事件被触发,"+this.id);
});
</script>
上述代码都是采用的事件冒泡机制:
-
点击孩子元素,先孩子元素再父亲元素
-
点击父亲元素
<script type="text/javascript">
document.getElementById("parent").addEventListener("click",function(e){
console.log("parent事件被触发,"+this.id);
},true);
document.getElementById("child").addEventListener("click",function(e){
console.log("child事件被触发,"+this.id);
},true);
</script>
上述代码都是采用的事件捕获机制:
-
点击孩子元素,先父亲元素再孩子元素
-
点击父亲元素
事件委托
当有多个类似的元素需要绑定事件时,一个一个去绑定即浪费时间,又不利于性能,这时候就可以用到事件委托,给他们的一个共同父级元素添加一个事件函数去处理他们所有的事件情况.
<ul id="1ist">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
document.getElementById('1ist').addEventListener('click',function(e){
e.target.innerHTML = "被点击";
});
上述代码才用事件委托机制,虽然我们没有给每个li绑定事件,我们绑定事件的时候是采用的默认的冒泡,所以可以理解为点击之后冒泡执行的;
-
点击li元素