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


313

考虑以下:

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

如何做到这一点,以便当用户单击跨度时不会触发div的click事件?

Answers:


272

使用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>

11
FireFox中没有事件对象。
罗伯特·巴特

6
事件对象是回调的参数。实际上,在IE中没有事件对象,因为可以通过window.event而不是函数的参数来访问该对象:-)
文森特·罗伯特

66
这是错误的-内联onclick处理程序不会使事件作为参数传递。正确的解决方案是下面的Gareths。
Benubird 2010年

2
在Firefox中,您可以使用内联脚本访问变量事件,但是window.event不可用。<div onclick =“ alert(event);”> </ div>
Morgan Cheng

1
event似乎也可以在IOS Safari的内联事件中使用。
Yuval A.

210

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

  1. 在与W3C兼容的浏览器(Chrome,Firefox,Safari,IE9 +)中的第一个参数
  2. Internet Explorer中的window.event对象(<= 8)

如果您需要支持不遵循W3C建议的旧版浏览器,通常在一个函数中,您将使用以下内容:

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

它会先检查一个,然后再检查另一个,并存储在事件变量中找到的那个。但是,在嵌入式事件处理程序中,没有e要使用的对象。在这种情况下,您必须利用arguments始终可用的集合,并引用传递给函数的完整参数集:

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

但是,通常来说,如果需要停止传播之类的复杂操作,则应避免使用内联事件处理程序。就可读性和可维护性而言,从中期和长期来看,分别编写事件处理程序并将其附加到元素上是一个更好的主意。


11
您可以从内联侦听器中传递事件对象,例如:onclick="foo(event)",然后在函数中传递function foo(event){/* do stuff with event */}。这适用于IE和W3C事件模型。
RobG 2014年

5
“小于或等于8”有点...模棱两可。
TechNyquist '16

8
这实际上并不能回答问题。
jcomeau_ictx

1
另一个问题的简洁答案。:-/
Arel

80

请记住,FireFox不支持window.event,因此它必须符合以下要求:

e.cancelBubble = true

或者,您可以将W3C标准用于FireFox:

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;
    }
}

12
为了使其正常工作,需要这样称呼:<div onclick="myEventHandler(event);">
DarkDust 2010年

1
可能是“事件|| window.event”。
尖尖的

1
如果(e.cancelBubble)看起来不正确,请将其设置为true(如果它已经为真)
Guillaume86

e.cancelBubble在IE中返回false!无法达到e.cancelBubble = true;指令。请改用SoftwareARM的条件!!
mauretto 2012年

45

使用此功能,它将测试是否存在正确的方法。

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

20

我有同样的问题-IE中的js错误框-就我所知,这在所有浏览器中都可以正常运行(event.cancelBubble = true在IE中可以完成工作)

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

1
谢谢@MSC,正是我所需要的!
DannyC 2015年

1
内联脚本。它确实回答了问题
Cesar

10

这对我有用

<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处理程序中有一个字符串引用问题...?!
妮可

7

对于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
}


2

由于因果关系,我无法评论,因此我将其作为整体答案来写:根据Gareth的答案(var e = arguments [0] || window.event; [...]),我在onclick上使用此oneliner内联用于快速破解:

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

我知道已经很晚了,但是我想让您知道这可以一行完成。大括号返回在两种情况下都具有stopPropagation-function的事件,因此我尝试将它们封装在大括号中,如if和.... it一样。:)


1

这也有效-在链接HTML中,将onclick与return一起使用,如下所示:

<a href="mypage.html" onclick="return confirmClick();">Delete</a>

然后,comfirmClick()函数应类似于:

function confirmClick() {
    if(confirm("Do you really want to delete this task?")) {
        return true;
    } else {
        return false;
    }
};

2
这不是问题的意思。
jzonthemtn

@jbird正是这个问题的意思。这是一种通过取消冒泡dom树来取消事件的不同(较旧的)方法(属于dom api级别1规范)。
gion_13

@ gion_13但是用户不需要确认单击的动作。在问题中,我们只希望激发孩子的onclick(),而不希望父母的onclick()。在两者之间放置用户提示没有帮助。希望您能看到这种区别。
jzonthemtn

1
confirm是不相关的。我指的是返回值。quote:在链接HTML中,使用onclick 和这样的return
gion_13

在链接之后返回false取消,它不会取消我的chrome上的传播
commonpike

1

为什么不只检查单击了哪个元素?如果单击某项,window.event.target则将其分配给单击的元素,然后被单击的元素也可以作为参数传递。

如果目标和元素不相等,则这是一个向上传播的事件。

function myfunc(el){
  if (window.event.target === el){
      // perform action
  }
}
<div onclick="myfunc(this)" />

谢谢伙伴,这似乎是这里最干净的解决方案。在旁注中,您必须考虑到,这仅在被单击的元素是实际最顶部的元素时才匹配。
西蒙·马特斯

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

0

最好的解决方案是通过javascript函数处理事件,但为了直接使用html元素使用简单快捷的解决方案,并且一旦不赞成使用“ event”和“ window.event”并且不受普遍支持(https://developer.mozilla.org/zh-CN/docs/Web/API/Window/event),我建议使用以下“硬代码”:

<div onclick="alert('blablabla'); (arguments[0] ? arguments[0].stopPropagation() : false);">...</div>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.