简体   繁体   English

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

[英]How do I prevent a parent's onclick event from firing when a child anchor is clicked?

I'm currently using jQuery to make a div clickable and in this div I also have anchors.我目前正在使用 jQuery 来制作一个可点击的 div,在这个 div 中我也有锚点。 The problem I'm running into is that when I click on an anchor both click events are firing (for the div and the anchor).我遇到的问题是,当我点击一个锚点时,两个点击事件都会触发(对于 div 和锚点)。 How do I prevent the div's onclick event from firing when an anchor is clicked?单击锚点时如何防止触发 div 的 onclick 事件?

Here's the broken code:这是损坏的代码:

JavaScript JavaScript

var url = $("#clickable a").attr("href");

$("#clickable").click(function() {
    window.location = url;
    return true;
})

HTML HTML

<div id="clickable">
    <!-- Other content. -->
    <a href="http://foo.example">I don't want #clickable to handle this click event.</a>
</div>

Events bubble to the highest point in the DOM at which a click event has been attached.事件冒泡到 DOM 中附加点击事件的最高点。 So in your example, even if you didn't have any other explicitly clickable elements in the div, every child element of the div would bubble their click event up the DOM to until the DIV's click event handler catches it.因此,在您的示例中,即使您在 div 中没有任何其他显式可单击元素,div 的每个子元素也会将其单击事件在 DOM 中冒泡,直到 DIV 的单击事件处理程序捕获它。

There are two solutions to this is to check to see who actually originated the event.有两种解决方案是检查谁实际发起了该事件。 jQuery passes an eventargs object along with the event: jQuery 将 eventargs 对象与事件一起传递:

$("#clickable").click(function(e) {
    var senderElement = e.target;
    // Check if sender is the <div> element e.g.
    // if($(e.target).is("div")) {
    window.location = url;
    return true;
});

You can also attach a click event handler to your links which tell them to stop event bubbling after their own handler executes:您还可以将点击事件处理程序附加到您的链接,告诉他们在自己的处理程序执行后停止事件冒泡

$("#clickable a").click(function(e) {
   // Do something
   e.stopPropagation();
});

Use stopPropagation method, see an example:使用stopPropagation方法,看一个例子:

$("#clickable a").click(function(e) {
   e.stopPropagation();
});

As said by jQuery Docs:正如jQuery Docs所说:

stopPropagation method prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event. stopPropagation方法防止事件在 DOM 树中冒泡,防止任何父处理程序收到事件通知。

Keep in mind that it does not prevent others listeners to handle this event (ex. more than one click handler for a button), if it is not the desired effect, you must use stopImmediatePropagation instead.请记住,它不会阻止其他侦听器处理此事件(例如,一个按钮的多次单击处理程序),如果它不是所需的效果,则必须使用stopImmediatePropagation代替。

Here my solution for everyone out there looking for a non-jQuery code (pure javascript)这是我为寻找非jQuery代码(纯javascript)的每个人提供的解决方案

document.getElementById("clickable").addEventListener("click", function( e ){
    e = window.event || e; 
    if(this === e.target) {
        // put your code here
    }
});

Your code wont be executed if clicked on parent's childs如果单击父母的孩子,您的代码将不会被执行

If you do not intend to interact with the inner element/s in any case , then a CSS solution might be useful for you.如果您在任何情况下都不打算与内部元素交互,那么 CSS 解决方案可能对您有用。

Just set the inner element/s to pointer-events: none只需将内部元素设置为pointer-events: none

in your case:在你的情况下:

.clickable > a {
    pointer-events: none;
}

or to target all inner elements generally:或一般针对所有内部元素:

.clickable * {
    pointer-events: none;
}

This easy hack saved me a lot of time while developing with ReactJS在使用 ReactJS 进行开发时,这个简单的 hack 为我节省了很多时间

Browser support could be found here: http://caniuse.com/#feat=pointer-events浏览器支持可以在这里找到: http ://caniuse.com/#feat=pointer-events

you can also try this你也可以试试这个

$("#clickable").click(function(event) {
   var senderElementName = event.target.tagName.toLowerCase();
   if(senderElementName === 'div')
   {
       // do something here 
   } 
   else
   {
      //do something with <a> tag
   }
});

Inline Alternative:内联替代方案:

<div>
    <!-- Other content. -->
    <a onclick='event.stopPropagation();' href="http://foo.example">I don't want #clickable to handle this click event.</a>
</div>

Writing if anyone needs (worked for me):写如果有人需要(为我工作):

event.stopImmediatePropagation()

From this solution.这个解决方案。

如果可点击 div 中有多个元素,则应执行以下操作:

$('#clickable *').click(function(e){ e.stopPropagation(); });

Using return false;使用return false; or e.stopPropogation();e.stopPropogation(); will not allow further code to execute.将不允许进一步的代码执行。 It will stop flow at this point itself.它会在此时停止流动。

I compare to ev.currentTarget when this is not available (React, etc).this不可用时(React 等),我与ev.currentTarget进行比较。

$("#clickable").click(function(e) {
    if (e.target === e.currentTarget) {
        window.location = url;
        return true;
    }
})

Here's an example using Angular 2+这是使用 Angular 2+ 的示例

For example, if you wanted to close a Modal Component if the user clicks outside of it:例如,如果您想在用户单击模态组件外部时关闭它:

// Close the modal if the document is clicked.

@HostListener('document:click', ['$event'])
public onDocumentClick(event: MouseEvent): void {
  this.closeModal();
}

// Don't close the modal if the modal itself is clicked.

@HostListener('click', ['$event'])
public onClick(event: MouseEvent): void {
  event.stopPropagation();
}

 var inner = document.querySelector("#inner"); var outer = document.querySelector("#outer"); inner.addEventListener('click',innerFunction); outer.addEventListener('click',outerFunction); function innerFunction(event){ event.stopPropagation(); console.log("Inner Functiuon"); } function outerFunction(event){ console.log("Outer Functiuon"); }
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>Pramod Kharade-Event with Outer and Inner Progration</title> </head> <body> <div id="outer" style="width:100px;height:100px;background-color:green;"> <div id="inner" style="width:35px;height:35px;background-color:yellow;"></div> </div> </body> </html>

如果它是在内联上下文中,在 HTML 中试试这个:

onclick="functionCall();event.stopPropagation();

e.stopPropagation()是一个正确的解决方案,但如果您不想将任何事件处理程序附加到您的内部锚点,您可以简单地将这个处理程序附加到您的外部 div:

e => { e.target === e.currentTarget && window.location = URL; }

You need to stop the event from reaching (bubbling to) the parent (the div).您需要阻止事件到达(冒泡)父级(div)。 See the part about bubbling here , and jQuery-specific API info here .请参阅此处有关冒泡的部分,以及此处的 jQuery 特定 API 信息。

You can check whether the target is not your div-element and then issue another click event on the parent after which you will "return" from the handle.您可以检查目标是否不是您的 div 元素,然后在父级上发出另一个单击事件,之后您将从句柄“返回”。

$('clickable').click(function (event) {
    let div = $(event.target);
    if (! div.is('div')) {
       div.parent().click();
       return;
    }
    // Then Implement your logic here
}

Here is a non jQuery solution that worked for me.这是一个对我有用的非 jQuery 解决方案。

 <div style="background:cyan; width:100px; height:100px;" onclick="if (event.srcElement==this) {console.log('outer');}"> <a style="background:red" onclick="console.log('inner');">Click me</a> </div>

To specify some sub element as unclickable write the css hierarchy as in the example below.要将某些子元素指定为不可点击,请编写 css 层次结构,如下例所示。

In this example I stop propagation to any elements (*) inside td inside tr inside a table with the class ".subtable"在此示例中,我停止传播到具有类“.subtable”的表内的 td 内 tr 内的任何元素 (*)

$(document).ready(function()
{    
   $(".subtable tr td *").click(function (event)
   {
       event.stopPropagation();
   });

});

In case someone had this issue using React, this is how I solved it.如果有人在使用 React 时遇到了这个问题,我就是这样解决的。

scss: scss:

#loginBackdrop {
position: absolute;
width: 100% !important;
height: 100% !important;
top:0px;
left:0px;
z-index: 9; }

#loginFrame {
width: $iFrameWidth;
height: $iFrameHeight;
background-color: $mainColor;
position: fixed;
z-index: 10;
top: 50%;
left: 50%;
margin-top: calc(-1 * #{$iFrameHeight} / 2);
margin-left: calc(-1 * #{$iFrameWidth} / 2);
border: solid 1px grey;
border-radius: 20px;
box-shadow: 0px 0px 90px #545454; }

Component's render():组件的渲染():

render() {
    ...
    return (
        <div id='loginBackdrop' onClick={this.props.closeLogin}>
            <div id='loginFrame' onClick={(e)=>{e.preventDefault();e.stopPropagation()}}>
             ... [modal content] ...
            </div>
        </div>
    )
}

By a adding an onClick function for the child modal (content div) mouse click events are prevented to reach the 'closeLogin' function of the parent element.通过为子模式(内容 div)添加 onClick 函数,可以防止鼠标单击事件到达父元素的“closeLogin”函数。

This did the trick for me and I was able to create a modal effect with 2 simple divs.这对我有用,我能够用 2 个简单的 div 创建模态效果。

ignoreParent() is a pure JavaScript solution. ignoreParent()是一个纯 JavaScript 解决方案。

It works as an intermediary layer that compares the coordinates of the mouse click with the coordinates of the child element/s.它作为一个中间层,将鼠标点击的坐标与子元素的坐标进行比较。 Two simple implementation steps:两个简单的实现步骤:

1. Put the ignoreParent() code on your page. 1.将 ignoreParent() 代码放在您的页面上。

2. Instead of the parent's original onclick="parentEvent();" 2.代替父级原来的onclick="parentEvent();" , write: , 写:

onclick="ignoreParent(['parentEvent()', 'child-ID']);"

You may pass IDs of any number of child elements to the function, and exclude others.您可以将任意数量的子元素的 ID 传递给函数,并排除其他元素。

If you clicked on one of the child elements, the parent event doesn't fire.如果您单击其中一个子元素,则不会触发父事件。 If you clicked on parent, but not on any of the child elements [provided as arguments], the parent event is fired.如果您单击了父元素,但没有单击任何子元素 [作为参数提供],则会触发父事件。

ignoreParent() code on Github Github 上的 ignoreParent() 代码

If a child element is clicked, then the event bubbles up to the parent and event.target !== event.currentTarget.如果单击子元素,则事件会冒泡到父元素和 event.target !== event.currentTarget。

So in your function, you can check this and return early, ie:因此,在您的函数中,您可以检查并提前返回,即:

var url = $("#clickable a").attr("href");
$("#clickable").click(function(event) {
    if ( event.target !== event.currentTarget ){
        // user clicked on a child and we ignore that
        return;
    }
    window.location = url;
    return true;
})

for those that are not using jQuery对于那些不使用 jQuery 的人

document.querySelector('.clickable').addEventListener('click', (e) =>{
    if(!e.target.classList.contains('clickable')) return
    // place code here
})

This is what you are looking for这就是你要找的

mousedown event. mousedown事件。 this works on every DOM elements to prevent javascript focus handler like this:这适用于每个 DOM 元素,以防止像这样的 javascript 焦点处理程序:

$('.no-focus').mousedown(function (e) {
   e.prevenDefault()

   // do stuff
}

in vue.js framework, you can use modifier like this:vue.js框架中,你可以像这样使用修饰符:

<span @mousedown.prevent> no focus </span>

Note that using on the input will prevent text selection handler请注意,在输入上使用将阻止文本选择处理程序

add a as follows: a如下:

<a href="http://foo.example" onclick="return false;">....</a>

or return false;return false; from click handler for #clickable like:来自#clickable的点击处理程序,例如:

  $("#clickable").click(function() {
        var url = $("#clickable a").attr("href");
        window.location = url;
        return false;
   });

All solution are complicated and of jscript.所有的解决方案都很复杂并且属于 jscript。 Here is the simplest version:这是最简单的版本:

var IsChildWindow=false;

function ParentClick()
{
    if(IsChildWindow==true)
    {
        IsChildWindow==false;
        return;
    }
    //do ur work here   
}


function ChildClick()
{
    IsChildWindow=true;
    //Do ur work here    
}
<a onclick="return false;" href="http://foo.example">I want to ignore my parent's onclick event.</a>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 反应如何防止在单击孩子时触发父母的 onclick 事件? - React how to prevent a parent's onclick event from firing when a child is clicked? 如何在单击子项时停止为父元素触发onclick事件? - How can I stop an onclick event from firing for parent element when child is clicked? 单击活生子时,如何禁用父级的onclick? - How do I disable the onclick of parent when live child is clicked? 当孩子的 onClick 被触发时触发向父级注册的 onKeyUp 事件 - Firing onKeyUp event registered with parent when child's onClick is fired 当选择了on选项时,如何防止ASP.NET下拉列表触发onclick事件? - How do you prevent a ASP.NET drop down list from firing it's onclick event when on option is selected? React JS - 单击子 onClick 时阻止父 onClick - React JS - Prevent Parent onClick when clicked on child onClick 如何防止父母 onclick 对使用 javascript 的孩子采取行动 - how do I prevent parent onclick action on child using javascript parent div中的onclick和另一个div中参数化的function同时被触发。 我如何防止父母解雇? - The onclick in the parent div and the parameterized function in the other div are triggered at the same time. How do I prevent the parent from firing? 使用Leaflet / MarkerCluster / Label,如何在添加标记时阻止“ onclick”触发? - Using Leaflet/MarkerCluster/Label, how do I prevent the 'onclick' from firing when adding a marker? 从子级拖动到父级时如何防止父级单击事件 - How to prevent parent click event when dragging from child to parent
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM