Javascript 如何防止父母';单击子锚点时触发的onclick事件?

Javascript 如何防止父母';单击子锚点时触发的onclick事件?,javascript,jquery,event-propagation,Javascript,Jquery,Event Propagation,我目前正在使用jQuery使一个div可点击,在这个div中我也有锚。我遇到的问题是,当我单击一个锚时,两个单击事件都会触发(对于div和锚)。如何防止在单击锚时触发div的onclick事件 以下是被破坏的代码: JavaScript var url = $("#clickable a").attr("href"); $("#clickable").click(function() { window.location = url; return true; }) HTML

我目前正在使用jQuery使一个div可点击,在这个div中我也有锚。我遇到的问题是,当我单击一个锚时,两个单击事件都会触发(对于div和锚)。如何防止在单击锚时触发div的onclick事件

以下是被破坏的代码:

JavaScript

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

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

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

使用方法,请参见示例:

$("#clickable a").click(function(e) {
   e.stopPropagation();
});
正如jQuery文档所说:

stopPropagation
方法防止事件在DOM中冒泡 树,防止任何父处理程序收到事件通知

请记住,它不会阻止其他侦听器处理此事件(例如按钮的多个单击处理程序),如果效果不理想,则必须使用
stopImmediatePropagation


<a onclick="return false;" href="http://foo.com">I want to ignore my parent's onclick event.</a>

事件冒泡到DOM中已附加单击事件的最高点。因此,在您的示例中,即使div中没有任何其他可显式单击的元素,div的每个子元素都会将其单击事件冒泡到DOM中,直到div的单击事件处理程序捕捉到它为止

对此有两种解决方案,即检查事件的始作俑者。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;
});

添加
a
,如下所示:

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

您需要阻止事件到达(冒泡到)父级(div)。
请参阅关于冒泡的部分,以及jQuery特定的API信息。

所有解决方案都很复杂,都是jscript的。以下是最简单的版本:

var IsChildWindow=false;

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


function ChildClick()
{
    IsChildWindow=true;
    //Do ur work here    
}

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

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

要将某些子元素指定为不可链接,请编写css层次结构,如下例所示

在本例中,我停止了对类为“.subtable”的表中td和tr中的任何元素(*)的传播


这里是我为所有寻找非jQuery代码(纯javascript)的人提供的解决方案


如果使用
返回false单击家长的孩子,您的代码将不会执行
e.stopPropogation()将不允许执行更多代码。它会在这一点上停止流动。

您也可以试试这个

$("#clickable").click(function(event) {
   var senderElementName = event.target.tagName.toLowerCase();
   if(senderElementName === 'div')
   {
       // do something here 
   } 
   else
   {
      //do something with <a> tag
   }
});
$(“#可点击”)。点击(功能(事件){
var senderElementName=event.target.tagName.toLowerCase();
如果(senderElementName==='div')
{
//在这里做点什么
} 
其他的
{
//用tag做点什么
}
});
如果有人需要(为我工作)写作:


来自解决方案。

如果您在任何情况下都不打算与内部元素交互,那么CSS解决方案可能对您有用

只需将内部元素设置为
指针事件:无

就你而言:

.clickable > a {
    pointer-events: none;
}
或以所有内部元素为目标:

.clickable * {
    pointer-events: none;
}
在使用ReactJS开发时,这个简单的hack为我节省了很多时间


可以在此处找到浏览器支持:

以下是使用Angular 2的示例+

例如,如果用户在模态组件外部单击,则要关闭该组件:

// 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();
}

如果有人使用React遇到此问题,我就是这样解决的

scss:

组件的渲染()

render(){
...
返回(
{e.preventDefault();e.stopPropagation()}>
…[模态内容]。。。
)
}
通过为子模式(content div)添加onClick函数,可以防止鼠标单击事件到达父元素的“closeLogin”函数

这对我来说很有帮助,我可以用两个简单的div创建一个模态效果

var-inner=document.querySelector(“#inner”);
var outer=document.querySelector(“外部”);
addEventListener('click',innerFunction);
outer.addEventListener('click',outerFunction);
函数内部函数(事件){
event.stopPropagation();
控制台日志(“内部函数”);
}
函数outerFunction(事件){
控制台日志(“外部功能”);
}

Pramod Kharade事件与外部和内部进展
ignoreParent()是一个纯JavaScript解决方案

它作为一个中间层,将鼠标单击的坐标与子元素的坐标进行比较。两个简单的实施步骤:

1。将ignoreParent()代码放在页面上

2.代替父级的原始onclick=“parentEvent();”,写下:

onclick="ignoreParent(['parentEvent()', 'child-ID']);"
您可以将任意数量的子元素的ID传递给函数,并排除其他元素

如果单击其中一个子元素,则不会触发父事件。如果您单击了父元素,但没有单击任何子元素[作为参数提供],则会触发父事件

内联备选方案:

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

如果它在内联上下文中,请在HTML中尝试以下操作:

onclick="functionCall();event.stopPropagation();
e.stopPropagation()
是一个正确的解决方案,但如果您不想将任何事件处理程序附加到内部锚点,只需将此处理程序附加到外部div即可:

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

您可以检查目标是否不是您的div元素,然后在父元素上发出另一个click事件,之后您将从句柄“返回”

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

如果单击了子元素,则事件将冒泡到父元素和event.target!==event.currentTarget

因此,在您的函数中,您可以检查此项并提前返回,即:

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;
})

这里有一个非jQuery的解决方案,对我来说很有效


点击我

不可用时(React等),我将其与
ev.currentTarget
进行比较


这就是您要找的

mousedown
事件。这适用于每个DOM元素,以防止javascript焦点处理程序如下所示:

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

   // do stuff
}
<span @mousedown.prevent> no focus </span>
vue.js
框架中,可以使用如下修改器:

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

   // do stuff
}
<span @mousedown.prevent> no focus </span>
<
e => { e.target === e.currentTarget && window.location = URL; }
$('clickable').click(function (event) {
    let div = $(event.target);
    if (! div.is('div')) {
       div.parent().click();
       return;
    }
    // Then Implement your logic here
}
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;
})
$("#clickable").click(function(e) {
    if (e.target === e.currentTarget) {
        window.location = url;
        return true;
    }
})
$('.no-focus').mousedown(function (e) {
   e.prevenDefault()

   // do stuff
}
<span @mousedown.prevent> no focus </span>