禁止父级 div 中的子元素触发点击事件

3

我正在尝试添加一个点击事件到一个类为 parent 的 div 元素上。该元素中有一个类为 child 的 div 元素,它也有自己的点击事件。

如何才能禁用父元素的点击事件以便执行子元素自己的函数?

我尝试使用 pointer-event:none; 但似乎它并没有起作用。我已经创建了一个 jsfiddle,以便更好地理解:

https://jsfiddle.net/arq1epbs/

$(document).on('click', '.parent', function() {
  var url = $(this).attr("data-url")
  document.location.href = url
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent" data-url="www.google.com">
  Im the parent
  <div class="child">
    im the child and I don't want to go to Google
  </div>
</div>

非常感谢您提前提供的所有帮助!


我有一个带有class为child的div,它有自己的点击事件。但是这个例子没有展示如何/何时将该点击事件注册到子元素上。 - t.niese
我喜欢舔屏活动的想法,我认为这种限制让我们所有人都非常沮丧 ;) - Mister Jojo
4个回答

4
你可以使用 stopPropagation()
 $(document).on('click', '.parent', function () {
    var url = $(this).attr("data-url")
    document.location.href = url 
});
 $(document).on('click', '.child', function (e) {
 e.stopPropagation();
});

由于它在Stack Snippet中无法正常工作,这里提供一个Fiddle进行参考。 参考:stopPropagation()


1

您可以在子元素的点击事件中简单地调用 event.stopPropagation(),以防止事件从DOM树向上冒泡,防止任何父处理程序被通知子元素的点击事件,例如:

$(document).on('click', '.parent', function() {
  //var url = $(this).attr("data-url")
  //document.location.href = url
  console.log('Parent Clicked');
});

$(document).on('click', '.child', function(event) {
  event.stopPropagation();
  console.clear();
  console.log('Child Clicked');
});
.parent{background:#99c0c3;width:350px;height:120px;position:relative}
.child{background:#ffde99;width:300px;height:50%;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent" data-url="www.google.com">
  Im the parent
  <div class="child">
    im the child and I don't want to go to Google
  </div>
</div>


“防止事件冒泡到DOM树”的说法在这种情境下有点误导。由于此处使用了事件委托,两个事件都被捕获在文档元素上,因此事件已经冒泡到了文档元素。 - t.niese

1

Just add this line:

$(document).on('click', '.parent', function (e) {
    if(e.target !== this) return false;   //This line added
    var url = $(this).attr("data-url")
    document.location.href = url 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent" data-url="www.google.com">
Im the parent
  <div class="child">
  im the child and I don't want to go to Google
  </div>
</div>


0

你可以使用“纯”JS来实现这个功能

document.querySelector('div.parent').onclick = evt =>
  {
  if (!evt.target.matches('div.parent')) return // reject sub elements click

  document.location.href = evt.target.dataset.url
  }
div.parent { cursor: pointer }
div.child { cursor: default }
<div class="parent" data-url="www.google.com">
  Im the parent
  <div class="child">
    Im the child and I don't want to go to Google
  </div>
</div>


你应该避免在较大的代码库中使用 onclick - t.niese
@t.niese onclick的优点在于它拒绝在同一元素上使用其他addEventListener,从而避免了在过于粗糙的代码中产生任何混淆。 - Mister Jojo
onclick 不会阻止使用 addEventListener 添加更多的监听器,也不会覆盖已经使用 addEventListener 注册的任何事件监听器。它只会覆盖之前分配给 onclick 的事件监听器,这就是为什么在实际代码中它是有问题的原因。 - t.niese
@t.niese,你所发现的问题恰恰是一个有用的约束。 - Mister Jojo
在您自己的项目中,如何解决问题最终取决于您,因为只有您需要处理错误和问题。但是对于那些被他人使用或由多个人共同开发的大型项目,您应该遵循一定的指导方针。 onclick 的唯一好处是从代码的某个部分中删除元素中的侦听器,而这部分代码并不拥有或知道该侦听器,并且您不知道该侦听器存在的原因或如何以不同的方式将其删除。如果是这种情况,则代码已经存在常规问题。 - t.niese
@t.niese确实,大型项目或管理事件的混乱会给管理带来真正的灾难。 - Mister Jojo

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