您的位置:首页 > Web前端 > JavaScript

JavaScript事件冒泡和事件委托

2016-03-10 14:19 661 查看
JavaScript中事件流是开发过程中常用到的知识,我们需要理解熟练掌握其基本原理和使用场景。

JavaScript可以监控页面上元素的各种事件,常用的事件有很多,例如点击,鼠标移入、移出,元素改变等等。这次主要说一下事件冒泡及其一个比较酷的应用,事件委托。不做特殊说明,以下都在jQuery框架内执行。

事件冒泡

什么是“事件冒泡”呢?假设这里有一杯水,水被用某种神奇的方式分成不同颜色的几层。这时,从最底层冒出了一个气泡,气泡会一层一层地上升,直到最顶层。而你不管在水的哪一层观察都可以看到并捕捉到这个气泡。好了,把“水”改成“DOM”,把“气泡”改成“事件”。这就是“事件冒泡”。

为了可以直观地观察到这一现象,我写了一个小程序。这个页面中一共有4个嵌套的正方形。最大的那个在最顶层,最小的那个在最底层。我为每一层都单独绑定了一个点击事件,当这一层被点击时,会为这层涂色。试试看,点击最小的正方形会发生什么?点击其他的又会发生什么呢?

CSS

.white{background-color:#fff;}
#d1{width:400px;height:400px;border:1px solid #000;margin:50px50px;}
#d2{width:300px;height:300px;border:1px solid #000;margin:50px50px;}
#d3{width:200px;height:200px;border:1px solid #000;margin:50px50px;}
#d4{width:100px;height:100px;border:1px solid #000;margin:50px50px;}


HTML

<div id="d1"class="white">
<div id="d2"class="white">
<div id="d3"class="white">
<div id="d4"class="white"></div>
</div>
</div>
</div>
<button id="reset1">重置</button>


Javascript

jQuery('#d4').click(function(){jQuery(this).css('background-color','yellow')});
jQuery('#d3').click(function(){jQuery(this).css('background-color','green')});
jQuery('#d2').click(function(){jQuery(this).css('background-color','blue')});
jQuery('#d1').click(function(){jQuery(this).css('background-color','red')});
jQuery('#reset1').click(function(){jQuery('.white').css('background-color','#fff')});




没错,点击最小的那个,外面所有的都会被上色。你会发现,点击里层的正方形,外层所有的正方形都会被上色。因为它们也都捕捉到了点击事件。看,他们抓到“气泡”了!

事件委托

上一节的例子我们做一点小小的修改。气泡带上了某种信息,会告诉其经过的每一层自己是在哪一层产生的。JavaScript的事件确实会带着这个属性。当程序捕获一个事件的时候,它会知道这个事件来自于页面上哪个元素。修改上面的程序,使用事件委托来处理点击事件。当最顶层捕获点击事件时,查看事件来源于哪一层,然后只将那一层涂色。再次点击每一层,查看实际效果。只有当前点击的正方形变色了,其他的都毫无反应。

jQuery('#d1').click(function(e){
vart=jQuery(e.target);
varid=t.attr('id');
if(id==='d4'){
t.css('background-color','yellow');
}elseif(id==='d3'){
t.css('background-color','green');
}elseif(id==='d2'){
t.css('background-color','blue');
}else{
t.css('background-color','red');
}
});


当然,如果你有这样嵌套的页面元素,使用了事件委托,委托到了最顶层,这时需要注意:如果其中某个元素,你不希望它的事件冒泡,那么可以使用某种方式阻止事件的冒泡。在jQuery框架中,可以使用stopPropagation()方法来实现而不必关心浏览器兼容性。

$('#bind').click(function(){
if($(this).is(':checked')){
$('#d4').bind('click',function(e){
e.stopPropagation();
alert('冒泡被阻止,这块将不会改变颜色');
});
}else{
$('#d4').unbind('click');
}
});


重置后选中“阻止最小的方块的事件冒泡”,再点击最小的方块,看是否变色。显然是不会变色,阻止了冒泡,父层将无法接收到点击事件。

注意事项

事件委托是事件冒泡的一个应用,可以减少绑定元素的个数,也不必担心子节点被替换后可能需要进行重新的事件绑定。因为事件的捕获和后续代码的执行已经完全委托给了其父节点。如果页面中含有大量元素需要绑定事件,这样做会减少事件绑定数量,为浏览器减负,无疑会提高页面性能。

但也有些需要注意的。如果用于捕获事件的节点会在某些情况下return false,而你的一个点击事件未委托给父节点,那么,你可能需要阻止这个节点的事件冒泡来达到正确的目的。例如:我在一个div里面有一些按钮和其他元素。利用事件委托来处理这些按钮的点击,如果不是按钮则return false。这时,错误就出现了。如果其他元素中含有链接,那么链接的点击事件也会被委托给div。然而点击链接,会没有任何反应。解决办法一是在委托的代码中对链接进行处理,二是阻止链接的事件冒泡。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript jquery 事件