如何在点击儿童时只触发父级点击事件 [英] How to ONLY trigger parent click event when a child is clicked
问题描述
孩子和父母都是可点击的(孩子可能是带有jQuery点击事件的链接或div)。当我点击孩子时,我该如何触发父级点击事件而不是子级事件?
活动分为三个阶段: 事件也有一个默认操作,它在冒泡阶段之后发生。默认操作是浏览器定义的操作,通常针对作为事件目标的元素种类上指定类型的事件发生(例如浏览器导航到 有关捕获和冒泡的更多信息,请参阅:什么是事件冒泡和捕获?; DOM 3级事件草案;或者 W3C DOM4:Events 为了您想要的事情,要在事件发生之前将事件发送给父母,并防止事件发生在孩子身上,必须在捕获阶段接收事件。一旦在捕获阶段收到它,您必须停止事件传播到DOM树中较低元素的任何事件处理程序,或者已经注册在冒泡阶段侦听的所有事件处理程序(即,所有侦听器在元素/阶段在你的听众之后被事件访问)。您可以通过致电 当使用 引用MDN: [ 在以下示例中,事件侦听器位于父和 jQuery不支持在事件上使用捕获。有关原因的详细信息,请参阅:为什么jQuery事件模型不支持事件捕获并仅支持事件冒泡 Both child and parent are clickable (child could be a link or div with jQuery click events). When I click on child, how do I only trigger parent click event but not the child event? Events have three phases: Events also have a "default action", which happens after the bubbling phase. The default action is the browser-defined action that normally occurs for events of the specified type on the kind of element which is the target of the event (e.g. the browser navigating to the The DOM Level 3 Events draft has a diagram that graphically shows how events propagate through the DOM: For more information, on capture and bubbling, see: "What is event bubbling and capturing?"; The DOM Level 3 Events draft; or W3C DOM4: Events For what you want, to get the event on the parent prior to, and prevent, the event on the child, you have to receive the event in the capture phase. Once you have received it in the capture phase, you have to stop the event from propagating to any event handlers on elements lower in the DOM tree, or which have registered to listen in the bubbling phase (i.e. all listeners on elements/phases which would be visited by the event after your listener). You do this by calling When adding the listener with Quoting MDN: [
In the following example, event listeners are placed on both the parent and the child
jQuery does not support using capture on events. For more information as to why see: "Why does jQuery event model does not support event Capture and just supports event bubbling" 这篇关于如何在点击儿童时只触发父级点击事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
< window>
开始调用,并通过后代向下移动到事件目标。
href
< a>
在点击
后显示,而点击$ c> $ b> b
的c> href [这在下面的例子中使用,但没有实际效果,因为没有文本的默认操作。在这里使用它是因为大多数时候您要添加一个单击事件处理程序来防止默认操作。因此,养成这样做的习惯是一个好主意,而当你知道你不想这样做的时候不这样做。]
图片版权所有©2016 万维网联盟,( MIT , ERCIM , Keio ,< a href =http://ev.buaa.edu.cn/ =noreferrer>北航)。 http://www.w3.org/Consortium/Legal/2015/doc-license (根据许可证允许使用)
< h1>阻止事件发生给孩子
event.stopPropagation( )
。
在拍摄阶段接收事件
addEventListener(type,listener)添加侦听器[,useCapture])
,您可以将 useCapture
参数设为 true
。
useCapture
is]一个布尔值,指示此类型的事件将在调度到DOM树下的任何EventTarget之前分派给注册的侦听器。在树中冒泡的事件不会触发指定使用捕获的侦听器。当两个元素都注册了该事件的句柄时,事件冒泡和捕获是传播嵌套在另一个元素中的元素中发生的事件的两种方式。事件传播模式确定元素接收事件的顺序。有关详细说明,请参阅DOM Level 3事件和JavaScript事件顺序。如果未指定, useCapture
默认为false。
防止其他处理程序获取事件
event.stopPropagation()
是用于防止稍后在任何事件阶段收到事件的元素的处理程序。它不会阻止调用当前元素和阶段上的任何其他处理程序。它不会阻止发生默认操作。
event.stopImmediatePropagation()
:相同元素和阶段的处理程序按添加顺序调用。除了与 event.stopPropagation()
具有相同的效果外, event.stopImmediatePropagation()
还可以阻止任何其他处理程序在相同的元素和事件阶段接收事件。它不会阻止发生默认操作。鉴于这个问题的要求是防止事件传播给孩子,我们不需要使用它,但可以这样做,而不是使用 event.stopPropagation()
。但请注意,同一元素上的侦听器按照它们添加的顺序被调用。因此, event.stopImmediatePropagation()
不会阻止这些侦听器在与侦听器之前添加的侦听器相同的元素和阶段接收事件。
示例
< div>
元素的子元素。只有放在父级上的侦听器才会收到该事件,因为它在子级之前的捕获阶段接收到该事件,并执行 event.stopPropagation()
。
< input id =preventChildtype =checkboxchecked>阻止儿童获取事件< / input>< div id =parent>父文字< br /> < div id =childstyle =margin-left:10px;>儿童文字< br /> < / div>< / div>
h2>
DOM Event Phases
<window>
and moving down through descendants towards the target of the event.href
of an <a>
upon a click
, whereas a click
on another type of element will have a different default action).
Image Copyright © 2016 World Wide Web Consortium, (MIT, ERCIM, Keio, Beihang). http://www.w3.org/Consortium/Legal/2015/doc-license (Use permitted per the license)Preventing the event from getting to the child
event.stopPropagation()
.Receiving events during the capture phase
addEventListener(type, listener[, useCapture])
, you can have the useCapture
argument be true
.
useCapture
is] A Boolean that indicates that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree. Events that are bubbling upward through the tree will not trigger a listener designated to use capture. Event bubbling and capturing are two ways of propagating events that occur in an element that is nested within another element, when both elements have registered a handle for that event. The event propagation mode determines the order in which elements receive the event. See DOM Level 3 Events and JavaScript Event order for a detailed explanation. If not specified, useCapture
defaults to false.Preventing other handlers getting the event
event.preventDefault()
is used to prevent the default action (e.g. prevent the browser from navigating to the href
of an <a>
upon a click
). [This is used in the example below, but has no real effect as there is no default action for text. It's used here because most of the time when you are adding a click event handler you want to prevent the default action. Thus, it's a good idea to be in the habit of doing so, and just not doing so when you know you don't want to.]event.stopPropagation()
is used to prevent any handlers on elements later in any of the event phases from receiving the event. It does not prevent any additional handlers on the current element and phase from being called. It does not prevent the default action from occurring.event.stopImmediatePropagation()
: Handlers on the same element and phase are called in the order in which they are added. In addition to having the same effect as event.stopPropagation()
, event.stopImmediatePropagation()
prevents any additional handlers on the same element and event phase from receiving the event. It does not prevent the default action from occurring. Given that the requirement for this question is to prevent the event from propagating to children, we don't need to use this, but could do so instead of using event.stopPropagation()
. Note, however, that listeners on the same element are called in the order they are added. Thus, event.stopImmediatePropagation()
will not prevent the event from being received by those listeners on the same element and phase as your listener which were added prior to your listener.Example
<div>
elements. Only the listener placed on the parent receives the event because it receives the event during the capture phase prior to the child and it executes event.stopPropagation()
.var parent=document.getElementById('parent');
var child=document.getElementById('child');
var preventChild=document.getElementById('preventChild');
parent.addEventListener('click',function(event){
if(preventChild.checked) {
event.stopPropagation();
}
event.preventDefault();
var targetText;
if(event.target === parent) {
targetText='parent';
}
if(event.target === child) {
targetText='child';
}
console.log('Click Detected in parent on ' + targetText);
},true);
child.addEventListener('click',function(event){
console.log('Click Detected in child (bubbling phase)');
});
child.addEventListener('click',function(event){
console.log('Click Detected in child (capture phase)');
},true);
<input id="preventChild" type="checkbox" checked>Prevent child from getting event</input>
<div id="parent">Parent Text<br/>
<div id="child" style="margin-left:10px;">Child Text<br/>
</div>
</div>
jQuery