jQuery停止孩子触发父事件


208

我有一个div,我已经附加了一个onclick事件。在这个div中有一个带有链接的标签。当我单击链接时,onclick也会触发来自div 的事件。我如何禁用此功能,以便如果在div上单击链接onclick不会被触发?

脚本:

$(document).ready(function(){
    $(".header").bind("click", function(){
         $(this).children(".children").toggle();
    });
})

html代码:

<div class="header">
    <a href="link.html">some link</a>
    <ul class="children">
        <li>some list</li>
    </ul>
</div>

Answers:


411

做这个:

$(document).ready(function(){
    $(".header").click(function(){
        $(this).children(".children").toggle();
    });
   $(".header a").click(function(e) {
        e.stopPropagation();
   });
});

如果您想了解更多有关.stopPropagation()的信息,请查看此处


2
如果对某人有帮助,我将替换$(".header a")$(".header *")并选择了任何子项(div,表单,输入等)。
aldo.roman.nurena

1
e.stopPropagation(); 必须写在第一行,除非它不起作用!
ehsan 2013年

2
不幸的是,这种方法阻止了已rel配置的灯箱正常工作
eapo

5
xr280xr的以下答案要好得多,因为它不会干扰孩子的可能事件。
亚历山大·扬克

1
您创造的问题多于解决的问题。想象一下,第三方插件正在监听文档元素上的click事件。他们永远不会知道这些点击。请参阅有关灯箱的评论。
萨尔曼A

99

或者,可以使用传递给click事件处理程序的Event Object参数来确定是否单击了子级,而不是使用额外的事件处理程序来防止其他处理程序。target将是clicked元素,currentTarget并将是.header div:

$(".header").click(function(e){
     //Do nothing if .header was not directly clicked
     if(e.target !== e.currentTarget) return;

     $(this).children(".children").toggle();
});

8
对我来说,这是一个更优雅的解决方案,因为您不必为每个子元素都添加显式的preventDefault()。
Ryan Griggs

5
如果您对孩子有独立事件而不是公认的答案,那么它会起作用。绝对更干净,更好的解决方案
BozanicJosip

2
在大多数情况下,您无需担心,但是如果出于任何原因需要支持IE6-8,则它们不需要currentTarget。解决方法是将其替换this另一个答案中建议的方法。
亚历山大·扬克

这是比将额外的侦听器设置为仅捕获点击更干净的解决方案。
Micros

这段代码对我来说效果更好var target = $(e.target); if(!target.is(“ span”))return;`
Cr1xus

17

更好的方法是使用on()和链式链接,

$(document).ready(function(){
    $(".header").on('click',function(){
        $(this).children(".children").toggle();
    }).on('click','a',function(e) {
        e.stopPropagation();
   });
});

4

这里的答案从字面上完全理解了OP的问题。如何将这些答案扩展到存在许多子元素而不仅仅是一个<a>标签的情况下?这是一种方法。

假设您有一个带有黑色背景的照片库,并且照片集中在浏览器中。单击黑色背景(但不单击其中的任何内容)时,您要关闭叠加层。

以下是一些可能的HTML:

<div class="gallery" style="background: black">
    <div class="contents"> <!-- Let's say this div is 50% wide and centered -->
        <h1>Awesome Photos</h1>
        <img src="img1.jpg"><br>
        <img src="img2.jpg"><br>
        <img src="img3.jpg"><br>
        <img src="img4.jpg"><br>
        <img src="img5.jpg">
    </div>
</div>

这是JavaScript的工作方式:

$('.gallery').click(
    function()
    {
        $(this).hide();
    }
);

$('.gallery > .contents').click(
    function(e) {
        e.stopPropagation();
    }
);

这将停止.contents来自每个研究内部元素的点击事件,.gallery因此,仅当您在褪色的黑色背景区域中单击时,画廊才会关闭,而在内容区域中单击时,画廊不会关闭。这可以应用于许多不同的场景。


4

我偶然发现了这个问题,正在寻找另一个答案。

我想防止所有孩子触发父母。

JavaScript:

document.getElementById("parent").addEventListener("click",  function (e) {
    if (this !== event.target) return;
    // Do something
});

jQuery的:

$("#parent").click(function () {
    // Do something
}).children().on("click", function (e) {
    e.stopPropagation();
});

0

或这个:

$(document).ready(function(){
    $(".header").click(function(){
        $(this).children(".children").toggle();
    });
   $(".header a").click(function(e) {
        return false;
   });
});

2
@ Halcyon991 e通过参数以任何一种方式传递,e只是一个参考
qodeninja 2014年

@qodeninja是的,但是如果不使用,则不需要添加字符。
Halcyon991

没有添加return false任何链接的链接,它应该是可单击的。
2016年

0

最简单的解决方案是将此CSS添加到子级:

.your-child {
    pointer-events: none;
}

我需要这个由WordPress的增加不必要的字体标签和它的工作对我来说
NDM GJR

-1

一种更短的方法:

$('.header').on('click', function () {
    $(this).children('a').on('click', function(e) {
        e.stopPropagation();
        $(this).siblings('.children').toggle();
    });
});

但是...单击标题时,此操作不执行任何操作。
利奥拉·海顿

每次单击标题时,都会向子级('a')添加一个新的 click事件。
Frank Forte
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.