如何停止将事件从父 div 传播到子 div



我想在我的 html 中停止将事件从父div传播到子div。这里有一个简单的代码,我想做什么:

<div>
  <div id='categoryList'>
    <div class='listed-category'>
      <span>some content</span>
      <a id='close'>x</a> //"a" is used to remove the div
    </div>
  </div>
</div>
<div id='dropdown'>
</div>

在上面的代码中,如果我单击<div id='categoryList'> <div id='dropdown'>将通过波纹管代码上下滑动。

$(document).ready(function () {
    $('#categoryList').click(function (event) {
        event.preventDefault();
        event.stopPropagation();
        if ($('#dropdown').is(":visible")) {
            $('#dropdown').slideUp(400);
        }
        else {
            $('#dropdown').slideDown(400);
        }
    });
})

但是当我单击子<div class='listed-category'>执行上述 JavaScript 时,<div id='dropdown'>上下滑动。如何阻止这种情况?但是我希望能够单击<a id='close'>以删除子div

检查匹配点击对象的目标。在单击事件处理程序的开头尝试此代码。

if( event.target !== this ) {
       return;
}
//...do stuff.. 
你需要

停止在子级而不是父级中传播,所以你应该写这个:

 $('.listed-category').click(function(event){
    event.stopPropagation();
});

如果你想点击a标签并停止传播,你还需要写这个:

 $('a#close').click(function(event){
    event.stopPropagation();
});

无论如何,我会建议尤里的答案。我只是想让你知道你应该把event.stopPropagation()放在孩子身上(如果你不想运行父级的事件),而不是父级。

一个更优雅的解决方案是使用 CSS 并禁用子项上的指针事件。

#categoryList * {
    pointer-events: none;
}

或者,在特定情况下,listed-category 元素上没有事件:

#listed-category {
    pointer-events: none;
}

http://codepen.io/rakeshcode/pen/KrZdNo

$(document).ready(function(){
  $(".arrow").click(function(){
  $(".row").slideToggle();
  
  });
$(".btn").click(function(event){
   event.stopPropagation();
  //$(".btn").attr("href","www.yahoo.com")
});
})
.btn {
  display: block;
  padding:15px;
  background-color:green;
  width:100px;
  margin-top:15px;
  text-decoration:none;
  margin-left:auto;
  margin-right:auto;
  
  
  
}
.arrow {
  cursor:pointer;
  text-align: center;
  padding:10px 0;
  font-size:15px;
  font-weight:bold;
  background-color:grey;
  margin-top:15px;
}
.container {
  max-width:600px;
  margin-left:auto;
  margin-right:auto; 
}
.close {
  height:75px;
  overflow:hidden;
  transition-duration: 0.3s;  
  transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
}
.open {
  height:215px;
  overflow: hidden;
  transition-property:height;
  -moz-transition-duration: 0.3s;
    -webkit-transition-duration: 0.3s;
    -o-transition-duration: 0.3s;
    transition-duration: 0.3s;  
  transition-timing-function: ease-in;
}
.up {
  background-color:red; 
}
.down {
  background-color:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="arrow"> Click here Click here<a class="btn" href="www.google.com" target="_blank">click here</a></div>
  <div class="wrap">
  <div class="row">The most effective plac elearning,’ they most likely don’t know this themselves.Well, the most effective place to start is to dig into what the person asking for this training, ACTUALLY needs. Because if they’re dumping a huge stack of content on your desk and giving you vague instructions to ‘turn it into elearning,’ they most likely don’t know this themselves.Well, the most effective place to start is to dig into what the person asking for this training.ACTUALLY needs. Because if they’re dumping a huge stack of content on your desk and giving you vague instructions to ‘turn it into elearning,’ they most likely don’t know this themselves.Well, the most effective place to start is to dig into what the person asking for this trainingACTUALLY needs. Because if they’re dumping a huge stack of content on your desk and giving you vague instructions to ‘turn it into elearning,’ they most likely don’t know this themselves.Well, the most effective place to start is to dig into what the person asking for this training</div>
  </div>
  </div>

我建议你在div 中使用 unbind() 方法,而不是使用 e.stopPropagation,<div class='listed-category'>这样......

$('.listed-category').unbind('click');

这将允许停止.listed-categorydiv 的传播效果。方法e.stopPropagation()不起作用,因为它仅适用于父元素,而不适用于子元素。

您可以随时创建一个新函数并在之后分配给.listed-categorydiv。您还可以通过以下链接查看unbind()方法的文档:http://api.jquery.com/unbind/

我希望这有所帮助!

接受的答案是正确的,但在最佳情况下,当您有多个嵌套元素时,您不希望取消事件,而是获取实际单击的父容器并使用它。

$('.clicked-container').click((e) => {
    let t = e.target;
    while (!$(t).hasClass( "clicked-container" )) { t = t.parentNode; }
     
    ...
    $(t).toggleClass('active-or-whatever-you-want');
});

此外,当您在 ES6 中使用 Arrows => 时,接受答案中的"这个"不再指同一件事。您必须显式绑定此内容。

在 react 上使用 ref 防止事件冒泡的示例:

import React, { useRef } from "react";
const Modal = ({
  onClick,
}) => {
  const modalRef = useRef();
  return (
    <div
      ref={modalRef}
      onClick={(e) => {
        if (e.target !== modalRef.current) {
          return;
        }
        onClick();
      }}
    >
    </div>
  );
};
export default Modal;

参考

https://stackoverflow.com/a/28210173/5994546

最新更新