jquery停止子触发父事件

Posted

技术标签:

【中文标题】jquery停止子触发父事件【英文标题】:jquery stop child triggering parent event 【发布时间】:2011-01-22 19:20:16 【问题描述】:

我有一个 div,我附加了一个 onclick 事件。在这个 div 中有一个带有链接的标签。当我单击链接时,也会触发来自 div 的 onclick 事件。我怎样才能禁用它,以便如果单击 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>

【问题讨论】:

【参考方案1】:

这样做:

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

如果你想read more on .stopPropagation(), look here。

【讨论】:

如果它对某人有帮助,我将 $(".header a") 替换为 $(".header *") 并选择了任何孩子(div、表单、输入等)。 e.stopPropagation();必须写在第一行,除非它不起作用! 遗憾的是,这种方法阻止了 rel 配置的灯箱运行 xr280xr 下面的答案要好得多,因为它不会干扰孩子们可能发生的事件。 你创造的问题比你解决的要多。想象一下第三方插件监听文档元素上的点击事件。他们永远不会知道这些点击。请参阅有关灯箱的评论。【参考方案2】:

或者,您可以使用传递给单击事件处理程序的Event Object 参数来确定是否单击了子项,而不是使用额外的事件处理程序来阻止另一个处理程序。 target 将是被点击的元素,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();
);

【讨论】:

对我来说这是一个更优雅的解决方案,因为您不必为每个子元素添加显式 preventDefault()。 如果您对孩子有独立的事件,与公认的答案不同,它会起作用。绝对更清洁和更好的解决方案 在大多数情况下你不会关心这个,但如果出于某种原因你需要支持 IE6-8,他们do not have currentTarget。一种解决方法是将其替换为this,如another answer 中所建议的那样。 这比设置额外的监听器来捕获点击更简洁。 这段代码对我来说效果更好` var target=$(e.target); if(!target.is("span")) return;`【参考方案3】:

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

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

【讨论】:

@xr280xr - 抱歉,我将它与 .net 混淆了,其中从事件处理程序返回 false 是终止传播的一种方法。我删除了我的错误评论。【参考方案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();
);

【讨论】:

第一部分类似于 [xr280xr's] 早期的答案,但使用纯 javascript。第二个代码 sn-p 具有与接受的答案相同的限制/缺陷(请参阅那里的 cmets) - 而是使用第一个代码 sn-p 中显示的技术 - 请参阅 xr280xr 的答案,了解该更好的技术在 jquery 中的外观。【参考方案5】:

这里的答案太从字面上理解了 OP 的问题。如何将这些答案扩展到有许多子元素的场景,而不仅仅是一个 &lt;a&gt; 标签?这是一种方法。

假设您有一个背景涂黑的照片库,并且照片在浏览器中居中。当您单击黑色背景(但不是其中的任何内容)时,您希望覆盖关闭。

这里有一些可能的 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();
    
);

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

【讨论】:

【参考方案6】:

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

.your-child 
    pointer-events: none;

【讨论】:

我需要这个用于 Wordpress 添加的不需要的字体标签,它对我有用 这是我发现的最简单的方法【参考方案7】:

或者这个:

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

【讨论】:

@Halcyon991 e 通过参数以任一方式传递,e 只是一个参考 @qdeninja 是的,但如果不使用,则添加不必要的字符。 没有必要在链接中添加return false,它应该是可点击的。

以上是关于jquery停止子触发父事件的主要内容,如果未能解决你的问题,请参考以下文章

jquery事件冒泡

单击子锚点时,如何防止触发父级的 onclick 事件?

将元素附加到子元素会触发父元素中的 drop 事件

jq 在iframe中点击按钮,父元素触发事件

事件冒泡及事件委托的理解(JQuery Dom操作)

Jquery mouseover多次触发问题