• jquery 阻止事件冒泡


     这个是我在研究table里面有个button,两个标签都有click事件,怎样实现点击button不触发table的事件?试验了好几种方式都没有实现,今天看到这篇文章就把它留了下来,供后面的人学习使用。用过bind,unbind,one,live 都没有成功,突然想到了事件冒泡,然后就搜到了这篇文章。感谢zaq123q博主!

    事件的旅程:


    当页面上发生一个事件时,每个层次上的DOM元素都有机会处理这个事件。以下面的页面模型为例:

       1. <div class="foo">
       2.     <span class="bar"> 
       3.        下午茶-网页前端
       4.   </span>
       5.<p>jquery事件冒泡-下午茶-网页前端</p>
       6. </div>
    


    当在浏览器中形象化地呈现这些由嵌套的代码构成的元素时,我们看到的效果其实是这样的。

    DOM模型

    举例来说,如果单击了页面中的超链接(锚元素),那么</p><div>、<span>和 全都应该得到响应这次单击的机会。

    毕竟,这三个元素都同时处于用户的鼠标指针之下啊。

    允许多个元素响应单击事件的一种策略叫做“事件捕获”。在事件捕获的过程中,事件首先会交给最外层的元素,接着再交给更具体的元素。在这个例子中, 意味着单击事件首先会传递给</p><div>,然后是<span>,最后是</span>,如下面:

    事件捕获

    另一种相反的策略叫做“事件冒泡”。即当事件发生时,会首先发送给最具体的元素,在这个元素获得响应机会之后,事件会向上冒泡到更一般的元素。在我们的例子中,会首先处理事件,然后按照顺序依次是<span>和<div>,如下图所示:

    事件冒泡


    毫不奇怪,不同的浏览器开发者们最初采用的是不同的事件传播模型。因而,最终出台的DOM标准规定应该同时使用这两种策略:首先,事件要从一般到具体进行捕获,然后,事件再通过冒泡返回DOM树的顶层。而事件处理程序可以注册到这个过程中的任何一部分。

    但是,遗憾的通知大家,浏览器厂商,并不是这么做的。。
    并不是所有浏览器都为了与新标准保持一致而进行了更新,而且,对于那些支持捕获的浏览器来说,通常必须明确启用才行。为了提供跨浏览器的一致性,jquery始终会在事件模型的冒泡阶段注册事件处理程序。因此,我们总是可以假定最具体的元素会首先获得响应事件的机会。


    备注:FireFox运载标准事件模型(即同时支持捕获和冒泡),要把事件处理注册到捕获阶段,必须在标准的事件注册方法addEventListener()中将最后一个参数设置为true。

    IE的事件注册方法attachEvent()只能将事件处理程序注册到冒泡阶段。

    为了提供跨浏览器兼容性,jQuery始终会在模型的冒泡阶段注册事件处理程序(即为了和IE兼容啊。。),因此,我们总是可以假定最具体的元素会首先获得响应事件的机会。


    事件冒泡带来的问题:

    例子:

       1. <div id="switcher">
       2.    <h3>style switcher</h3>
       3.    <div id="switcher-normal" class="button selected">normal</div>
       4.    <div id="switcher-narrow" class="button">narrow column</div>
       5.    <div id="switcher-large" class="button">large print</div>
       6. </div>
       
    点击查看原始尺寸

     

    在上面的例子中说明了事件冒泡可能会导致问题的情形。

    javascript部分: 

       1. $(document).ready(function(){
    2.      $('#switcher').click(function(){
       3.            alert("aaaa")
       4.                                 })
       5. });
    

    上面的代码会使#switcher整个区域都可以通过单击触发事件运行alert命令,但是我们并不希望在#switcher里面的三个class=button的div单击时也运行alert,只是希望在黄色的区域响应单击事件并运行alert。

    导致这个问题的原因是:事件冒泡,即事件首先通过class=button的div处理,然后又沿着DOM树向上传递,直至到达


    阻止事件冒泡

    方法一:event.target == this

    要解决这个问题,必须访问事件对象(Event对象)。事件对象是一种javascript结构,它会在元素获得处理事件的机会时被传递给相应的事 件处理程序,这个对象中包含着与事件有关的信息(例如事件发生时的鼠标指针位置),也提供了可以用来影响事件在DOM中传递进程的一些方法。


    为了在处理程序中使用事件对象(Event对象),需要为函数添加一个参数:
    $('#switcher').click(function(event){....});

     
    事件目标

    现在,事件处理程序中的变量event保存着事件对象。而event.target属性(不过在IE中,是使用event.srcElement) 保存着发生事件的目标元素,即DOM中最里面最具体的元素,这个属性是DOM API中的规定的,但IE没有按照标准把事件对象传递给事件处理程序,而是把事件对象保存在全局属性window.event中,通过 windwo.enent.srcElement属性访问。但在jquery中,已经解决了这个浏览器兼容问题,统一使用“event.target属 性”就可以了。如果在javascript中,你可以这样引用event.target来解决浏览器兼容问题:

    var target=( (event.srcElement) ? event.srcElement : event.target )

    通过event.target,可以确定DOM中首先接收到事件的元素(即实际被单击的元素),而且,我们知道this引用的是处理事件的DOM元素,所以可以使用以下代码:

       1. $(document).ready(function(){
       2.   $('#switcher').click(function(event){
       3.     if(event.target == this){      alert("aaa")       }
       4.                                    })
       5. }};
    


    此时,代码确保了单击的元素是

    ,而不是其后代元素,现在单击class=button的div就不弹出alert了,而只会在单击黄色区域才会alert


    方法二:停止事件的传播 event.stopPropagation()

    事件对象还提供了一个event.stopPropagation()的方法,该方法可以完全阻止事件冒泡,与event.target类似,这个方法也是一种纯javascript特性,但在跨浏览器的环境中则无法完全地使用,不过,只要我们通过jquery来注册所有的事件处理程序,就可以放心使用这个方法了。


    继续以上面的例子,同样的html结构,
    如果去除(event.target==this)这个判断句的话,在上面的原代码的基础上,那么可以增加以下代码来阻止事件冒泡
    代码为:

       1. $(document).ready(function(){
       2.   $('#switcher .button').click(function(event){
       3.      event.stopPropagation(); 
       4.                                 })
       5. })
    

    同前面的一样,需要为用作单击处理程序的函数添加一个参数,以便访问事件对象,然后,通过简单地调用 event.stopPropagation()就可以避免其他所有DOM元素响应这个事件了。这样一来,在class=button的div上单击按钮 的事件就会被按钮处理,而且只会被按钮处理,只有单击黄色区域才会发生alert,因为在button处单击已经被阻止了冒泡到最外层的div上。

    下面是我做的一个小栗子:

    js,用了jquery插件

    $(document).ready(function(){
            function tabClick(){
                alert(222222);
                }

             $("#tab1").bind("click",tabClick);

            $('#btn1').click(function(event){
                     alert("1111111");
                    event.stopPropagation();
             });

     });

     html:

    <body>
    <table id="tab1" style="background:#CCC;border:1px solid #F00;" >
        <tr>
            <td>465566776</td>
            <td><input id="btn1" type="button" value="按钮"  />
            
            </td>
        </tr>
    </table>
    </body>

    大家可以粘贴走试试,再点击button的时候,没有触发table的click事件。

    文章来源:http://blog.csdn.net/dai_richard/article/details/7050144

  • 相关阅读:
    微软并行编程类库Parallel Extensions初探 Part1 (转)
    一些很酷的.Net技巧(上)
    【Silverlight】Silvelright端获取托管web项目中xap的路劲
    【Silverlight】Silvelright获取web端的xml
    博客开始第一天
    asp.net过滤HTML方法
    程序员应该懂的道理
    生成缩略图
    转:用自定义IHttpModule实现URL重写
    android 之helloword
  • 原文地址:https://www.cnblogs.com/lhwang/p/3715446.html
Copyright © 2020-2023  润新知