12

我有两个关于 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 事件......有什么想法吗?

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

提前感谢您的帮助,
马特

4

11 回答 11

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

于 2009-06-12T07:26:19.117 回答
5

For your second question, you can get the coordinates of the pointer when the click event occured, and compare them to the coordinates of the div. (actual implementation depends on which js library you use)

For your first question, to stop an event from bubbling, you have to use

event.cancelBubble = true;
if(event.stopPropagation) event.stopPropagation();
于 2009-06-12T08:46:06.930 回答
3

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

<div onclick="doSomething()">
     <input type="checkbox" onclick="event.stopPropagation()" onchange="doSomethingElse()" />
</div>
于 2014-05-08T22:01:04.240 回答
1

我遇到了与您的第一个问题非常相似的问题。但取而代之的是一个 <div> 和一个复选框,它是一个表格。看看我的非工作代码:

<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 时出现此警报

谷歌我怎么能做到这一点,我在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。

希望能帮助到你!

于 2014-11-13T19:06:05.583 回答
1

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

于 2009-06-12T07:25:53.737 回答
1

第二:

也可以看看:

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

[div onmousedown="clicking = true"
     onclick = " alert('child clicked") "
     onmouseup="clicking = false"
于 2010-10-10T11:29:45.450 回答
0

As well as or as an alternatative to stopping capturing the bubbling, each of your event functions should have some code that checks that the correct element has been clicked, use event.target, or event.scrElement in IE, to find the clicked element.

For your second question you probably want to use an image map, which is the HTML provided for clicking on a particular area of a image.

于 2009-06-12T08:20:50.047 回答
0

第二,您可以将您的 div 放在图像前面,并且在 div 中没有图像标签。这应该为您提供所需的功能。

于 2009-06-12T07:16:42.027 回答
0

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

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

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

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

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

于 2009-06-12T07:20:36.167 回答
0

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

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

于 2009-06-12T07:26:05.280 回答
0

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

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

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

希望这可以帮助。

于 2016-04-15T07:16:01.020 回答