多次遇到事件冒泡与捕获相关的题目,冒泡和捕获机制在不同浏览器中的兼容性也不相同,IE中默认只支持冒泡机制,冒泡和捕获都可以理解为事件的传播,很明显,在传播的情况下容易触发我们并不想触发的事件,这在项目中会产生意想不到的后果,所以有必要理解清楚事件传播机制,根据实际需要应用。
概念
冒泡
监听事件触发时,事件是从精确到不精确,从小范围到大范围,从底向上的一个顺序进行触发,也就是说首先执行当前最近的被选中的元素的事件,然后逐级向上执行父元素的事件,直至document或window(不同浏览器有不同)。
捕获
捕获机制和冒泡正好相反,事件触发顺序是从最不精确到最精确的当前被触发事件的元素。
作用:
- 事件冒泡允许多个操作被集中处理,把事件处理器添加到一个父级元素上,而避免了为每一个子元素都添加处理器。
- 让不同的对象同时捕获一件事情,就像老板给每个员工都分派好了事情,只待一声令下,员工开始在各自岗位执行自己的工作。
Demo演示
事件绑定
遵守W3C 标准的浏览器可以使用以下方式进行事件绑定
- addEventListener('Event', function(){},true/false)
第一个参数表示监听的事件名称,第二个参数是执行的动作,第三个参数将决定浏览器的响应方式,true表示浏览器采用capture响应方式,false表示浏览器采用bubble响应方式。 - 另一种方式是在JavaScript脚本中获取事件句柄(事件名称前加on就是事件句柄),并对事件句柄赋值处理函数,相关代码如下:
function Do(){
alert(" 你点击了一个button");
}
<button id="btn" onClick="Do()"></div> - IE中是默认采用冒泡方式,不支持addEventListener(),使用attachEvent绑定事件。attachEvent('event',function(){}),事件要加上on,如onclick,onmouseover...
- 阻止事件传播:支持W3C标准的浏览器可以在事件监听流中使用event.stopPropagation()来阻止事件继续传播。IE中在事件监听流中使用window.event.cancleBubble=true来阻止事件的冒泡。
实例与结果
- 演示图如下所示
页面结构代码如下
<body>
<div class="parent" id="bubPar">
<div class="child" id="bubChi">
<section id="bubSec">
<h3>JS事件冒泡演示</h3>
<p>
设置监听事件时,第三个参数值为“true”时,表示浏览器采用capture响应方式,false表示浏览器采用bubble响应方式。
</p>
<button id="btnBubble">冒泡</button>
</section>
</div>
</div>
<div class="parent" id="capPar">
<div class="child" id="capChi">
<section id="capSec">
<h3>JS事件捕获演示</h3>
<p>
当使用事件捕获时,符级元素先触发,子级元素后出发。
</p>
<button id="btnCapture">捕获</button>
</section>
</div>
</div>
</body>-
JS监听事件如下
<script type="text/javascript">
var bubPar=document.getElementById('bubPar');
bubPar.addEventListener("click",function(){
alert("1");
},false);
var bubChi=document.getElementById('bubChi');
bubChi.addEventListener("click",function(){
alert("2");
},false);
var bubSec=document.getElementById('bubSec');
bubSec.addEventListener("click",function(){
alert("3");
},false);
var btnBubble=document.getElementById('btnBubble');
btnBubble.addEventListener("click",function(){
alert("4");
},false);var capPar=document.getElementById('capPar'); capPar.addEventListener("click",function(){ alert("1"); },true); var capChi=document.getElementById('capChi'); capChi.addEventListener("click",function(){ alert("2"); },true); var capSec=document.getElementById('capSec'); capSec.addEventListener("click",function(){ alert("3"); },true); var btnCapture=document.getElementById('btnCapture'); btnCapture.addEventListener("click",function(){ alert("4"); },false); </script>
结果
- 点击冒泡按钮:浏览器窗口一次弹出弹框 4 3 2 1
- 点击捕获按钮:1 2 3 4
- 给捕获事件示例中的<section>元素的监听事件流中设置阻止事件的传播,代码如下:
var capSec=document.getElementById('capSec');
capSec.addEventListener("click",function(event){
alert("3");
event.stopPropagation();
},true);
此时点击捕获按钮:1 2 3
原因:<section>标签的监听事件中阻止了事件的传播,因此<button>标签的事件不会被捕获执行。- 给冒泡事件示例中的<section>元素的监听事件流中设置阻止事件的传播,代码如下:
var bubSec=document.getElementById('bubSec');
bubSec.addEventListener("click",function(event){
alert("3");
event.stopPropagation();
},false);
此时点击冒泡按钮:4 3
原因:首先是<button>标签的事件,然后是<section>,因为<section>标签的监听事件中阻止了事件继续冒泡,父级元素的事件不会被触发。