jQuery事件stopPropagation对自定义事件无效

3
<!DOCTYPE html>
<html>

<head>

<script src="jquery-2.1.1.min.js" type="text/javascript"></script>

</head>

<body>

<div id="outer">
    <div id="inner">
    </div>
</div>

<script type="text/javascript">

$("#outer").on("myevent", function(event) { 
    alert(event.target.id);
    event.stopPropagation();
    return false;
});

$("div").trigger("myevent");

</script>

</body>

</html>

在上面的代码中,我期望事件myevent只被outer div处理一次。但是我看到了两个警报:outerinner。为什么stopPropagation在这里不起作用,如何防止自定义事件传播到子元素?
编辑:我想全局触发事件,例如$("div").trigger("myevent");,但我只想在订阅事件的地方处理它。
3个回答

3

不要在$('#outer').on('myevent')上使用event.stopPropagation(),而是需要在每个div元素的独立处理程序中使用它:

$("#outer").on("myevent", function(event) { 
    console.log(event.target.id);
    return false;
});
$('div').on('myevent', function(event) { // or $('*').on('myevent', ...
    event.stopPropagation();
});

$("div").trigger("myevent"); // only logs 'outer'

http://jsfiddle.net/mblase75/z7NQy/


2

$("div").trigger("myevent"); 相当于:

$("div").each(function() {
    $(this).trigger("myevent");
});

因为jQuery会自动循环匹配选择器的所有元素。所以它会分别在内部和外部DIV上触发事件。
当它在内部DIV上触发时,那里没有处理程序,所以事件就会冒泡到外部DIV。
为了防止这种情况发生,您应该更具体地指定要触发的元素:
$("#outer").trigger("myevent");

我想触发事件,而不知道谁会处理它。否则,我可以只编写一个函数并将 div id 传递给它,而不是使用事件。 - rmflow
1
你可以将它发送到 #inner。当它冒泡出来时,它将由 #outer 处理。 - Barmar
是的,我可以在 #inner 中处理事件,它不会向上传播,但这并不是我想要的正解(我需要在处理程序中对 target 做一些操作)。看起来,由于对 JavaScript 事件的理解不足,我的问题完全无效。 - rmflow
1
听起来您可能想要使用事件捕获模型来处理您的事件。在文档上触发该事件,它将沿着DOM层次结构向下传播,并被#outer捕获。请参见https://dev59.com/4W445IYBdhLWcg3w9Oss。 - Barmar
@Barmar 那个答案说事件捕获模型并不被所有浏览器支持。 - Blazemonger

1
你会收到两个警报,因为你在
上触发了myevent,所以它将应用于html中所有可用的
。在这种情况下,你有内部和外部
,分别触发myevent

要在外部

上触发myevent,请使用:

$("div#outer").trigger("myevent");

演示


限定基于ID的选择器不仅是无意义的,因为ID是快速查找的,而且实际上会减慢选择器的速度。只需使用#outer即可。 - iCollect.it Ltd
@TrueBlueAussie 是的,如果 #outer 可能是不同类型的 DOM 元素,那么这并不是毫无意义的。 - Blazemonger
@Blazemonger:如果ID已知,而且显然必须是唯一的,如果在不同的页面上为不同的元素重用相同的ID,那么很可能会引起问题。我的观点依然成立。 - iCollect.it Ltd

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