【问题标题】:How can I stop an onclick event from firing for parent element when child is clicked?单击子元素时,如何阻止 onclick 事件触发父元素?
【发布时间】:2010-11-02 09:24:52
【问题描述】:

我有两个关于 onclick 事件的问题,它们有点相似,所以我会在这里问他们。

第一:

我在 div 中有一个复选框。输入有onchange函数,div有onclick函数。

<div onclick="doSomething()">
     <input type="checkbox" onchange="doSomethingElse()" />
</div>

问题是当我选中/取消选中复选框时,doSomething() 和 doSomethingElse() 都会触发。关于如何阻止这种情况发生的任何想法?我试过做 onchange="doSomethingElse(event)" 和 doSomethingElse(e) 函数我有 e.stopPropagation();这没有用。

第二:

我在 div 中有一张图片。 div 具有 onclick 功能,但图像没有。图像故意大于 div 并溢出到 div 之外。

-----------------------
|        image        |
|   ---------------   |
|   |     div     |   |
|   |             |   |
|   ---------------   |
|                     |
-----------------------

我只希望用户在 div 框的范围内单击时触发 onclick。但是,如果您单击已溢出到 div 外部的图像部分,也会触发 onclick 事件...有什么想法吗?

第一个问题对我来说比第二个问题更重要。但如果有人能同时回答这两个问题,那就太棒了!

提前感谢您的帮助,
马特

【问题讨论】:

  • 将此分成两篇文章。当您问两个“点击处理”问题时,主题并没有同时为这两个问题提供服务。

标签: javascript html events onclick


【解决方案1】:

我遇到了同样的问题。对我来说,它是另一个跨度标签中的跨度标签,用于侧边栏菜单。子类别应该在单击时切换打开,但在单击内容时则不会。但是通过'click'事件的属性,我想我找到了一个解决方案,并写了这个:

function sidebar_click(event)
{
    if (event.target == event.currentTarget)
        event.currentTarget.classList.toggle('open');
}

它仅在目标 = currentTarget 时运行。 Target 是您单击的项目, currentTarget 是事件处理程序链接到的项目。如果它们相同,则执行,如果不同,则不执行。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我遇到了与您的第一个问题非常相似的问题。但取而代之的是一个

    和一个复选框,它是一个表格。看看我的 NON WORKING 代码:
    <table>
      <tr onClick="alert('I expect this alert when Cell_1 or Cell_2 are clicked but not Cell_3')">
        <td>Cell_1</td>
        <td>Cell_2</td>
        <td onClick="alert('I expect this alert only when Cell_3 is clicked')">Cell_3</td>
      </tr>
    <table>
    

    单击 Cell_1 或 Cell_2,我的代码按预期工作,但单击 Cell_3 时却没有,因为它显示了 2 个警报。

    第一个是:

    “我希望只有在单击 Cell_3 时才会收到此警报”

    第二个是:

    我希望在单击 Cell_1 或 Cell_2 而不是单击 Cell_3 时出现此警报

    Google-ing 我怎么能做到这一点,我在 Quirksmode 上找到了 this briliant 的帖子。

    嗯,简单地说,我可以这样解决这个难题:

    <table>
      <tr onClick="alert('I expect this alert when Cell_1 or Cell_2 are clicked but not Cell_3')">
        <td>Cell_1</td>
        <td>Cell_2</td>
        <td onClick="Cell_3Alert(event)">Cell_3</td>
      </tr>
    <table>
    

    还有 Javascript:

    function Cell_3Alert(e) {
      alert('I expect this alert only when Cell_3 is clicked');
    
      if (!e) var e = window.event; 
      e.cancelBubble = true;
      if (e.stopPropagation) e.stopPropagation();
    }
    

    我已经测试过,它可以在 FireFox 3.6+、IE6+ 和 Chrome 上运行。

    希望对你有帮助!

    【讨论】:

      【解决方案3】:

      在您的第一个在 div 中带有复选框的示例中,onchange 与 onclick 事件不同,因此在 onchange 处理程序中调用 event.stopPropagation() 不会阻止外部 onclick 触发。您需要在复选框上添加一个额外的 onclick 处理程序,以防止点击冒泡。

      <div onclick="doSomething()">
           <input type="checkbox" onclick="event.stopPropagation()" onchange="doSomethingElse()" />
      </div>
      

      【讨论】:

        【解决方案4】:

        秒:

        另见:

        [img onmousedown="if (!clicking) alert('parent clicked') " ...]
        
        [div onmousedown="clicking = true"
             onclick = " alert('child clicked") "
             onmouseup="clicking = false"
        

        【讨论】:

          【解决方案5】:

          对于你的第二个问题,你可以在点击事件发生时获取指针的坐标,并将它们与div的坐标进行比较。 (实际实现要看你用的是哪个js库)

          对于您的第一个问题,要阻止事件冒泡,您必须使用

          event.cancelBubble = true;
          if(event.stopPropagation) event.stopPropagation();
          

          【讨论】:

            【解决方案6】:

            与停止捕获冒泡一样或作为替代方法,您的每个事件函数都应该有一些代码来检查是否点击了正确的元素,使用event.target 或@987654322 @在IE中,找到被点击的元素。

            对于您的第二个问题,您可能希望使用 图像映射,这是为单击图像的特定区域而提供的 HTML。

            【讨论】:

              【解决方案7】:

              对于您的第一个问题:IE 不支持stopPropagation(),您应该使用e.cancelBubble = true。只需先进行功能检查,找出应该使用哪种方法 (if (e.stopPropagation) {code})。

              对于您的第二个问题:也许包括处理点击事件的第二个 div?

              <div><img src="image.jpg"/></div>
              <div style="position:absolute" onclick="doSomething();"></div>
              

              然后正确定位第二个div

              【讨论】:

                【解决方案8】:

                第一次尝试也使用 e.preventBubble() 并从处理程序返回 false。

                第二个您可以捕获点击并检查事件的目标。如果您使用一些标准化事件的库,例如 jQuery,其中 e.target 返回您触发事件的确切元素,这是最简单的。另一种选择是将点击处理程序放在图像上,而不是放在图像溢出的任何容器上。

                【讨论】:

                  【解决方案9】:

                  您需要停止传播。您可以为此使用 jQuery:Stopping Propagation

                  【讨论】:

                    【解决方案10】:

                    我不确定您的第一个是否是简化的。如果确实是这样,我只需从 div 中完全删除 onClick。

                    但我怀疑你的实际案例更复杂,所以我并没有真正提供那个作为答案。

                    对于第二种情况,我实际上将图像分为五个部分,并且只将其中一个放在 div 中,如下所示:

                    +------------------------------------------------------+
                    |                     Image part 1                     |
                    +------------------------------------------------------+
                    | Image part 2 | Image part 3 (and div) | Image part 4 |
                    +------------------------------------------------------+
                    |                     Image part 5                     |
                    +------------------------------------------------------+
                    

                    Kludgy,我知道,但我倾向于先寻求最简单的解决方案。

                    【讨论】:

                    • 好主意,它肯定会奏效。但是我需要将图像保持在一块。不过谢谢!
                    【解决方案11】:

                    第二个,你可以把你的 div 放在图片的前面,而不是在 div 里面放图片标签。这应该为您提供所需的功能。

                    【讨论】:

                    • 图像必须在 div 中,我已经看过该选项。不过还是谢谢。
                    猜你喜欢
                    • 2011-07-03
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-12-28
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-12-07
                    • 2021-03-21
                    相关资源
                    最近更新 更多