如何停止将事件从父 div 传播到子 div
Posted
技术标签:
【中文标题】如何停止将事件从父 div 传播到子 div【英文标题】:How to stop propagating event from parent div to child div 【发布时间】:2015-03-28 09:45:59 【问题描述】:我想在我的 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
【问题讨论】:
【参考方案1】:检查匹配点击对象的目标。在单击事件处理程序的开头尝试此代码。
if( event.target !== this )
return;
//...do stuff..
【讨论】:
目前为止最好的解决方案——比内置的 api 更好,有点不做你想做的事 我建议使用event.target !== event.currentTarget
而不是this
,因为this
的上下文可以重新绑定。
出色的解决方案。埃齐奥的建议也有效。【参考方案2】:
你需要停止在孩子而不是父母中传播,所以你应该这样写:
$('.listed-category').click(function(event)
event.stopPropagation();
);
如果你也想点击a
标签并停止传播,你还需要这样写:
$('a#close').click(function(event)
event.stopPropagation();
);
无论如何,我会建议 Yuriy 的答案。我只是想让你知道你应该把event.stopPropagation()
放在childss中(如果你不希望运行父母的事件),而不是父母。
【讨论】:
如果有 3-4 个孩子,那么我们需要添加更多的事件处理程序吗? @YuriyNedostup 是的,你的方法比我的好。我只是想让他知道他应该把 event.stopPropagation() 放在孩子而不是父母。【参考方案3】: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>
【讨论】:
这里是例子【参考方案4】:建议你在 div <div class='listed-category'>
中使用 unbind() 方法,而不是使用 e.stopPropagation,就像这样...
$('.listed-category').unbind('click');
这将允许停止.listed-category
div 的传播效果。 e.stopPropagation()
方法不起作用,因为它只适用于父元素而不适用于子元素。
您始终可以创建一个新函数并在之后分配给.listed-category
div。您还可以在此链接查看unbind()
方法的文档:http://api.jquery.com/unbind/
希望对你有帮助!
【讨论】:
【参考方案5】:接受的答案是正确的,但在最好的情况下,当您有多个嵌套元素时,您不希望取消事件,而是获取实际单击的父容器并使用它。
$('.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 => 时,接受的答案中的“this”也不再指代同一事物。你必须明确地绑定它。
【讨论】:
附言。不要在 HTML 元素上尝试它;-)【参考方案6】:更优雅的解决方案是使用 CSS 并禁用子级的指针事件。
#categoryList *
pointer-events: none;
或者在您的特定情况下,listed-category
元素上没有事件:
#listed-category
pointer-events: none;
【讨论】:
【参考方案7】:在 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://***.com/a/28210173/5994546
【讨论】:
以上是关于如何停止将事件从父 div 传播到子 div的主要内容,如果未能解决你的问题,请参考以下文章
ReactJS setState 更改不会从父组件传播到子组件[重复]