事件冒泡的阻止和应用场景

本文介绍了事件冒泡的基本概念,包括其不同实现方式及如何阻止事件冒泡。此外,还详细探讨了事件冒泡在实际开发中的应用场景,如事件委托等技巧。

事件冒泡的原理

事件捕获其实有三种方式,事件冒泡只是其中的一种:(1)IE从里到外(inside→outside)的冒泡型事件。(2)Netscape4.0从外到里(outside→inside)的捕获型事件。(3)DOM事件流,先从外到里,再从里到外回到原点(outside→inside→outside)的事件捕获方法(似乎对象将触发两次事件处理,这有什么作用?鄙人不懂!)。

●不是所有的事件都能冒泡。以下事件不冒泡:blur、focus、load、unload。

●事件捕获方式在不同浏览器,甚至同种浏览器的不同版本中是有所区别的。如Netscape4.0采用捕获型事件解决方案,其它多数浏览器则支持冒泡型事件解决方案,另外DOM事件流还支持文本节点事件冒泡。

●事件捕获到达顶层的目标在不同浏览器或不同浏览器版本也是有区别的。在IE6中HTML是接收事件冒泡的,另外大部分浏览器将冒泡延续到window对象,即……body→documen→window。

●阻止冒泡并不能阻止对象默认行为。比如submit按钮被点击后会提交表单数据,这种行为无须我们写程序定制。


事件冒泡的阻止:

原生:

function cancelBubble(e) { 
var evt = e ? e : window.event; 
if (evt.stopPropagation) { 
//W3C 
evt.stopPropagation(); 

else { 
//IE 
evt.cancelBubble = true; 

jquery提供的方式:

方式一:event.stopPropagation();

例如:

$("#div1").mousedown(function(event){

event.stopPropaggation();

});

方法二:return   false;

例如:

$("#div1").mousedown(function(event){

return   false;

});


$("a").click(function(event){ 
event.preventDefault(); //阻止默认动作即该链接不会跳转。 
alert(4);//但是这个还会弹出 
event.stopPropagation();//阻止冒泡事件,上级的单击事件不会被调用 
return false;//不仅阻止了事件往上冒泡,而且阻止了事件本身 
}); 


return  false和stopPropagation的区别:

return false 不仅阻止了事件往上冒泡,而且阻止了事件本身。event.stopPropagation() 则只阻止事件往上冒泡,不阻止事件本身。



事件冒泡的应用:

(1)事件冒泡允许多个操作被集中处理(把事件处理器添加到一个父级元素上,避免把事件处理器添加到多个子级元素上),它还可以让你在对象层的不同级别捕获事件

<div onclick="eventHandle(event)" id="outSide" style="width:100px; height:100px; background:#000; padding:50px">


<div id="inSide" style="width:100px; height:100px; background:#CCC"></div>


</div>


<script type="text/javascript">


//本例子只在外面盒子定义了处理方法,而这个方法一样可以捕获到子元素点击行为并处理它。假设有成千上万子元素要处理,难道我们要为每个元素加“onclick="eventHandle(event)"”?显然没有这种集中处理的方法来的简单,同时它的性能也是更高的。


function eventHandle(e)


{


    var e=e||window.event;


    var obj=e.target||e.srcElement;


    alert(obj.id+' was click')


}


</script>

另外一个应用是<ul><li></li></ul>,往每个li元素加事件怎么加,遍历加吗,不是,应该吧事件加到父级元素中

$('#LocalLife_PopUp_layer').find('.SelectCity_Cont ul').click(function(e){
            var e=e||window.event;
            var obj=e.target||e.srcElement;
            $('#LocalLife_PopUp_layer').find('.SelectCity_Cont ul').find('i').removeClass("Selectmark");
            $(obj).find("i").addClass("Selectmark");
            var CityVal = $(obj).text();
            $('#DuohuiReturn_Nav').find("li:first").find("em").text(CityVal);
            ShowHide();
            return false;
        })

 

var e=e||window.event;
                 if(e&& e.stopPropagation()){
                    e.stopPropagation();
                 }else{
                    e.cancelBubble = true;
                 }

 


(2)让不同的对象同时捕获同一事件,并调用自己的专属处理程序做自己的事情,就像老板一下命令,各自员工做自己岗位上的工作去了。

【同时捕获同一事件例子】


总之,事件冒泡是把双刃剑,带来麻烦的同时带来了事件委托这一神器。就是讲子元素的事件通过冒泡的形式交给父级元素来执行。

有可能在开发的时候会遇到这种情况:如导航每一个栏目都要加一个事件,你可能会通过遍历来给每个栏目添加事件:

[javascript]  view plain  copy
  1. <ul id="parentUl">  
  2.         <li>我还是个孩子</li>  
  3.         <li>我还是个孩子</li>  
  4.         <li>我还是个孩子</li>  
  5.         <li>我还是个孩子</li>  
  6.         <li>我还是个孩子</li>  
  7.     </ul>  
  8.  var ul = document.getElementById('parentUl'),  
  9.             li = ul.getElementsByTagName('li');  
  10.     for (var i = 0; i<li.length;i++){  
  11.         li[i].onclick=function () {  
  12.             alert(this.innerHTML);  
  13.         }  
  14.     }  

这种方式来添加事件固然简单,但是需要多次操作DOM,如果有100、1000个同级的元素需要添加事件,这种方式简直不忍直视,

而且当我们动态添加新的Li元素的时候,新添加的Li元素是没有被绑定事件的


这种方式来添加事件固然简单,但是需要多次操作DOM,如果有100、1000个同级的元素需要添加事件,这种方式简直不忍直视,

而且当我们动态添加新的Li元素的时候,新添加的Li元素是没有被绑定事件的


[javascript]  view plain  copy
  1. var ul = document.getElementById('parentUl');  
  2.     ul.onclick=function (event) {  
  3.       var e = event||window.event,  
  4.               source = e.target || e.srcElement;//target表示在事件冒泡中触发事件的源元素,在IE中是srcElement  
  5.         if(source.nodeName.toLowerCase() == "li"){   //判断只有li触发的才会输出内容  
  6.             alert(source.innerHTML);  
  7.         }  
  8.         stopPropagation(e);                           //阻止继续冒泡  
  9.     };  
  10.     function addElement() {  
  11.         var li = document.createElement('li');  
  12.         li.innerHTML="我是新孩子";  
  13.         ul.appendChild(li);  
  14.     } 

事件冒泡捕获是JavaScript中事件传播的两个阶段,它们属于DOM事件流的一部分。理解这两个阶段可以帮助我们更灵活地处理事件。 ### 事件冒泡 事件冒泡是指事件从最具体的元素(事件目标)开始,然后向上传播到较不具体的节点(文档)。例如,如果你点击了一个按钮,这个点击事件会先在按钮上触发,然后传播到按钮的父级元素,再传播到父级的父级元素,以此类推,直到document对象。 ### 事件捕获 事件捕获是事件流的第一阶段,与事件冒泡相反。事件从最不具体的节点(document对象)开始,然后向下传播到具体的节点(事件目标)。 ### 实际应用场景 #### 场景1:菜单项点击事件 假设有一个下拉菜单,包含多个子菜单项。我们可以利用事件冒泡来简化事件处理逻辑。只需为整个菜单绑定一个事件监听器,而不是为每个菜单项单独绑定。 ```javascript document.getElementById('menu').addEventListener('click', function(event) { if (event.target && event.target.nodeName == 'LI') { alert('You clicked on: ' + event.target.textContent); } }); ``` #### 场景2:阻止事件传播 有时你可能需要阻止事件继续传播。比如在一个弹出框内,点击关闭按钮时,你不希望这个点击事件影响到弹出框外的其他元素。 ```javascript var closeBtn = document.getElementById('close-btn'); closeBtn.addEventListener('click', function(event) { event.stopPropagation(); alert('Close button clicked'); }); document.getElementById('popup').addEventListener('click', function() { alert('Popup clicked'); }); ``` ### 解释 在场景1中,通过事件冒泡,我们只需要为整个菜单设置一个事件监听器,减少了代码量并且提高了性能。在场景2中,使用`event.stopPropagation()`方法可以阻止事件继续冒泡或捕获,从而避免不必要的事件处理。 ### 注意事项 - 在实际开发中,过多地依赖事件冒泡可能会导致难以追踪的bug,因此要合理使用。 - 某些事件默认不会冒泡,如`focus``blur`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值