如何使用内联onclick属性停止事件传播?

382

考虑以下内容:

<div onclick="alert('you clicked the header')" class="header">
  <span onclick="alert('you clicked inside the header');">something inside the header</span>
</div>

当用户点击 span 时,如何使其不触发 div 的点击事件?

16个回答

365

使用event.stopPropagation()方法。

<span onclick="event.stopPropagation(); alert('you clicked inside the header');">something inside the header</span>

针对IE浏览器: window.event.cancelBubble = true

<span onclick="window.event.cancelBubble = true; alert('you clicked inside the header');">something inside the header</span>

12
在FireFox中并不存在"event object"这种对象。 - Robert C. Barth
6
事件对象是回调函数的一个参数。实际上,在IE中并不存在事件对象,因为这个对象可以通过window.event访问,而不是作为函数的参数传递 :-) - Vincent Robert
72
这是错误的 - 行内 onclick 处理程序不会将事件作为参数传递。正确的解决方案是下面的 Gareths。 - Benubird
2
在Firefox中,您可以在内联脚本中访问变量事件,但window.event不可用。<div onclick="alert(event);"></div> - Morgan Cheng
1
“event” 似乎在 IOS Safari 的内联事件中也可用。 - Yuval A.
显示剩余3条评论

223

从函数内部获取事件对象有两种方式:

  1. 在符合W3C标准的浏览器(Chrome,Firefox,Safari,IE9+)中使用第一个参数
  2. 在Internet Explorer(<=8)中使用window.event对象

如果需要支持不遵循W3C建议的旧版浏览器,在函数内通常会使用以下类似代码:

function(e) {
  var event = e || window.event;
  [...];
}

代码会首先检查第一个参数,再检查第二个参数,并将找到的参数存储在事件变量中。但在内联事件处理程序中,没有可用的e对象。在这种情况下,您必须利用始终可用并引用传递给函数的完整参数集的arguments集合:

onclick="var event = arguments[0] || window.event; [...]"

然而,一般来说,如果你需要做像停止事件传播这样复杂的操作,你应该避免使用内联事件处理程序。将事件处理程序单独编写,然后将它们附加到元素上,在中长期内会更好地提高代码的可读性和可维护性。


13
你可以通过内联监听器将事件对象传递,例如 onclick="foo(event)",然后在函数中使用 function foo(event){/* 使用事件对象进行操作 */}。这种方法适用于IE和W3C事件模型。 - RobG
6
“小于或等于八”这个说法有些含糊不清。 - Niki Romagnoli
8
这并没有实际回答问题。 - jcomeau_ictx
1
对于不同的问题,这是一个简洁的答案。 :-/ - Arel

86

请记住,window.event在FireFox中不被支持,因此必须使用类似以下内容的替代方法:

e.cancelBubble = true

或者,你可以在 FireFox 中使用 W3C 标准:

e.stopPropagation();

如果你想更加高级一些,可以这样做:

function myEventHandler(e)
{
    if (!e)
      e = window.event;

    //IE9 & Other Browsers
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    //IE8 and Lower
    else {
      e.cancelBubble = true;
    }
}

13
为了使其起作用,需要这样调用:<div onclick="myEventHandler(event);"> - DarkDust
1
它可以是 "event || window.event"。 - Pointy
1
如果 (e.cancelBubble) 对我来说不太对,如果它已经是 true,则将其设置为 true。 - Guillaume86
在IE中,e.cancelBubble返回false!它无法到达e.cancelBubble = true;指令。使用SoftwareARM的条件代替!! - mauretto

47

使用该函数,它将测试正确方法的存在性。

function disabledEventPropagation(event)
{
   if (event.stopPropagation){
       event.stopPropagation();
   }
   else if(window.event){
      window.event.cancelBubble=true;
   }
}

22

我有同样的问题 - 在IE中出现了js错误框 - 据我所知,这在所有浏览器中都能正常工作(在IE中,event.cancelBubble=true可以解决问题)

onClick="if(event.stopPropagation){event.stopPropagation();}event.cancelBubble=true;"

1
谢谢 @MSC,正是我所需要的! - DannyC
1
内联脚本。它回答了这个问题。 - Cesar

14

这对我起作用了

<script>
function cancelBubble(e) {
 var evt = e ? e:window.event;
 if (evt.stopPropagation)    evt.stopPropagation();
 if (evt.cancelBubble!=null) evt.cancelBubble = true;
}
</script>

<div onclick="alert('Click!')">
  <div onclick="cancelBubble(event)">Something inside the other div</div>
</div>

你确定这段代码片段对你有效吗?因为外部div的onclick处理程序似乎存在字符串引用问题...?! - Nicole

10
对于 ASP.NET 网页(非 MVC),您可以使用 Sys.UI.DomEvent 对象作为本机事件的包装器。
<div onclick="event.stopPropagation();" ...

或者,将事件作为参数传递给内部函数:

<div onclick="someFunction(event);" ...

而在 someFunction 中:

function someFunction(event){
    event.stopPropagation(); // here Sys.UI.DomEvent.stopPropagation() method is used
    // other onclick logic
}

10

由于Karma原因,我无法进行评论,因此我将整个答案写在这里:根据Gareth的答案(var e = arguments [0] || window.event; [... ]),我在onclick上使用了这个单行内联式以进行快速hack:

<div onclick="(arguments[0] || window.event).stopPropagation();">..</div>

我知道现在有点晚,但我想让你知道这个可以在一行中完成。花括号返回一个事件,在两种情况下都附有stopPropagation函数,所以我尝试将它们封装在花括号中,就像在if语句中一样...它可行:)


7
根据 这个页面,在IE中需要使用以下代码来阻止事件冒泡:event.cancelBubble = true。

6

使用单独的处理程序,例如:

function myOnClickHandler(th){
//say let t=$(th)
}

在 HTML 中,可以这样写:

<...onclick="myOnClickHandler(this); event.stopPropagation();"...>

甚至可以:

function myOnClickHandler(e){
  e.stopPropagation();
}

for:

<...onclick="myOnClickHandler(event)"...>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接