如何在单击子 div 时解除父 div 的单击事件绑定

5
<div id="addCompaniesModal">
    <div id="addCompany_map"></div>
    <div class="addMarkerBtn"></div>
</div>

你好,当我点击子元素addCompany_map时,父元素addCompaniesModal不应该被调用... 我已经尝试了一些方法,但是由于某种原因没有起作用... 点击子元素时父元素被选中了,有人可以为我解释一下解决方案吗?

$(document).on('click','#addCompany_map', function (e) {
    e.stopPropagation();
});

$('#addCompaniesModal').click(function(){
});

我根据您的一些意见对我的答案进行了更新,所以请务必查看。 - Ivan Ferić
5个回答

4

事件传播是从子元素到父元素的。

可能看起来你的第一行代码处理的是子div的点击事件,但是你指定的方式实际上是处理文档级别(因为你的选择器是$(document)),只有当它发生在子div上时才调用该方法(on('click','#addCompany_map'部分)。由于文档是addCompaniesModal div的父元素,所以它的点击处理程序将在addCompaniesModal div中使用的处理程序之后触发。

为了使其工作,你需要将代码更改为:

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

$('#addCompaniesModal').click(function(){

});

编辑:

我看到你在一些评论中提到,你使用 $(document).on('click', ... 的主要原因是因为你正在动态添加子div。

在这种情况下,有两种可行的方法来处理你的问题。

第一种方法是你也动态添加子div处理程序,并在删除时取消绑定。你可以使用以下方法:

function dynamicallyAddChildren(){
  var oldChildDiv = $('#addCompany_map');
  if (oldChildDiv.length > 0)
    oldChildDiv.off('click', handleChildDiv);
  // remove old child if needed and add new child divs
  newChildDiv.on('click', handleChildDiv);
}

function handleChildDiv(e){
  //do something
  e.stopPropagation();
}

$('#addCompaniesModal').click(function(){
});

第二种方法是使用$(document).on('click', ...这种方法,并同时使用子div和父div,像这样:

$(document).on('click','#addCompany_map', function (e) {
    e.stopPropagation();
});

$(document).on('click','#addCompaniesModal', function(){
});​

嗨,伊万,谢谢你的回复。我尝试了你的第二种方法,但结果还是一样的......你能否让你的第一种方法更加清晰明了吗?谢谢。 - troy
这种方法是基于在创建子div时动态添加点击处理程序。函数handleChildDiv(e)是您当前用于addCompany_map点击事件的函数。它是明确定义的,因此您可以绑定和解除绑定单击事件。函数dynamicallyAddChildren只是为了展示您如何使用它 - 当您创建addCompany_map div时,应调用$('#addCompany_map').on('click', handleChildDiv);。如果您在代码中的任何地方将该div从其父级中删除,则应使用$('#addCompany_map').off('click', handleChildDiv);取消绑定事件。 - Ivan Ferić
1
我创建了这个fiddle,以便您可以更清楚地看到 - http://jsfiddle.net/fera/HPmyM/。您可以使用“添加div”按钮动态添加您的div,并使用“删除div”按钮将它们删除。 - Ivan Ferić
1
谢谢你的努力,伊万......它正在工作......+1 你的解释......干杯 - troy

0

我认为:

$("#addCompany_map").click(function(){
  return false;
});

0
使用委托并检查目标元素。这样就可以在单个处理程序中处理所有三个div点击事件了。
$('body').on('click','#addCompaniesModal',function(e) {

    if (e.target.id === 'addCompany_map') {
        alert('Clicked Map Div !!')
    }
    else if (e.target.className === 'addMarkerBtn') {
        alert('Clicked Marker Div !!')
    }
    else {
        alert('Parent Div !!')
    }
});​

检查 Fiddle


嗨,我尝试了你的方法,但它没有起作用,因为我的addCompany_map和addMarkerBtn是动态添加的... - troy
无论我点击哪里,它都会进入else分支...可能是因为我的子div是动态添加的... - troy

0

使用这个表达式作为您问题的最简单解决方案:

$('#addCompaniesModal').on('click','div', function (e) {
    console.log(e.target.id || e.target.className);
    e.stopPropagation();
});

这也会提高性能,就如reference所说:尽量避免在大型文档上为委托事件过度使用document或document.body。 因此你可以一举两得。

第二个表达式可以保持不变:

$('#addCompaniesModal').click(function(){
});

顺便提一下.click(handler).on("click", handler) 的快捷方式。


0

你在#addCompaniesModal上有一个点击事件,其中包括#addCompany_map。因此,通过单击子元素,您也将单击父元素。

看起来你需要问自己想要实现什么。如果您希望对父元素中的子元素执行特定操作,则应删除父元素上的点击事件。如果您想在父元素内的另一个对象(而不是#addCompany_map)上具有点击事件,例如.addMarkerBtn,那么就这样做。但是,您上面的方式行不通。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接