我目前使用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.example">I don't want #clickable to handle this click event.</a>
</div>

使用stopPropagation方法,见示例:

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

正如jQuery文档所说:

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

请记住,它不会阻止其他侦听器处理此事件(例如。),如果不是想要的效果,你必须使用stopImmediatePropagation代替。


<a onclick="return false;" href="http://foo.example">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;
});

你也可以附加一个点击事件处理程序到你的链接,告诉他们在他们自己的处理程序执行后停止事件冒泡:

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

添加a如下:

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

或者返回false;从点击处理程序#clickable像:

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

您需要阻止事件到达父节点(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中的任何元素(*)

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

});

这里是我的解决方案,每个人都在寻找一个非jquery代码(纯javascript)

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

如果点击父级的子级,你的代码将不会被执行


使用返回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
    }
});

如果有人需要写信(为我工作过):

event.stopImmediatePropagation()

从这个解。


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

只需将内部元素/s设置为pointer-events: none

在你的情况下:

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

或笼统地针对所有内部元素:

.clickable * {
    pointer-events: none;
}

这个简单的hack在用ReactJS开发时为我节省了很多时间

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


下面是一个使用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:

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

组件的呈现():

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

通过为子模式(content div)添加onClick函数,可以防止鼠标点击事件到达父元素的“closeLogin”函数。

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


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>


内联选择:

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

如果它在内联上下文中,在HTML中尝试这样做:

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

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

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

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

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

如果单击子元素,则事件将弹出到父元素和事件。== event. currentarget。

所以在你的函数中,你可以检查这个并提前返回,即:

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解决方案。

< div风格= "背景:青色;宽度:100 px;" onclick="if (event.srcElement==this) {console.log('outer');} <a style="background:red" onclick="console.log('inner');我“>点击< / > < / div >


和ev比较。当这个不可用时(React等)。

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

这就是你要找的

mousedown事件。这适用于每个DOM元素,以防止javascript的焦点处理程序,像这样:

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

   // do stuff
}

在vue.js框架中,你可以这样使用修饰符:

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

注意,使用on输入将阻止文本选择处理程序


对于那些没有使用jQuery

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