如何在单击子项时停止为父元素触发onclick事件?

时间:2009-06-12 07:12:52

标签: javascript html events onclick

我在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事件也会触发......有什么想法吗?

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

提前感谢您的帮助,
马特

11 个答案:

答案 0 :(得分:8)

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

对于你的第二个问题:可能包括处理点击事件的第二个div?

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

然后正确定位第二个div

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

第二

另见:

[img onmousedown="if (!clicking) alert('parent clicked') " ...]

[div onmousedown="clicking = true"
     onclick = " alert('child clicked") "
     onmouseup="clicking = false"

答案 5 :(得分:1)

我的第一个问题问题非常类似。但改为&lt; div&gt;还有一个复选框,它是一张桌子。查看我的非工作代码:

<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我如何管理,我在this briliant上发现Quirksmode帖子。

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

<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。

希望它有帮助!

答案 6 :(得分:0)

对于第二个,您可以将div放在图像前面,而不是div中的图像标记。这应该为您提供所需的功能。

答案 7 :(得分:0)

我不确定你的第一个是否是简化版。如果这正是它的原因,我只需从div中删除onClick。

但我怀疑你的实际案例更复杂,所以我并不是真的提供那个答案。

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

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

Kludgy,我知道,但我倾向于首先选择最简单的解决方案。

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

除了或作为停止捕捉冒泡的替代方案之外,您的每个事件函数都应该有一些代码检查是否已点击了正确的元素,使用event.target或IE中的event.scrElement,用于查找单击的元素。

对于第二个问题,您可能想要使用图片地图,这是为点击图片的特定区域而提供的HTML。

答案 10 :(得分:0)

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

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

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

希望这有帮助。