如何将点击事件传递或冒泡到另一层?

时间:2019-04-17 19:44:52

标签: javascript jquery

我正在研究一个项目,我需要对其进行编辑并对元素进行一些操作。我在组DIV中有一些DIV作为元素,另一个DIV覆盖了它们。我的问题是,当我单击叠加并执行一些操作时,我也希望单击叠加下面的任何元素。

我尝试起泡,但是由于overlay元素不在同一div中,因此对我不起作用。我也尝试过手动触发事件,但是由于我不知道单击该元素的位置下方的哪个元素,因此无法获得预期的结果。 我还发现这篇文章How to pass click events from one div to another?与我的问题类似,但不完全是因为我还需要在点击时对覆盖层进行一些操作。

$(document).ready(function() {
  $('#group').on('mousedown', function(evt) {
    // Do some action
    console.log('group');
  });
  $('#overlay').on('mousedown', function(evt) {
    // Do some action
    console.log('cover');
  });
  $('.item').on('mousedown', function(evt) {
    // Do some action
    console.log('item-' + $(this).html());
    evt.stopPropagation()
  });
});
#group {
	width: 400px;
	height: 400px;
	position: relative;
	background-color: #eee;
}

#overlay {
	position: absolute;
	top: 50px;
	left: 50px;
	width: 250px;
	height: 250px;
	background-color: #000;
	opacity: 0.2;
	z-index: 10;
}

.item {
	position: absolute;
	width: 150px;
	height: 150px;
	font-size: 4rem;
	line-height: 140px;
	text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="overlay"></div>
<div id="group">
	<div class="item" style="top: 60px; left: 60px; background-color: #fcc;">A</div>
	<div class="item" style="top: 170px; left: 170px; background-color: #cfc;">B</div>
</div>

我希望在单击叠加层时希望也可以单击叠加层下面的任何“项目” div。
我使用了jQuery,但是可以接受任何使用原始JavaScript的解决方案。

2 个答案:

答案 0 :(得分:0)

您尝试执行的操作听起来像是反模式。浏览器并非旨在将同一点击应用于多个项目。相反,您应该问自己,为什么需要在多个元素上处理相同的事件,并以不同的方式重新设计UI和业务逻辑,所以不必要。就像,您有一个可在点击时调用的通用方法,并且使您的下层和上层都调用相同的方法。

也就是说,如果您确实需要类似这样的内容,例如对于光标下具有多个项目的游戏,则需要实现手动点击检测,而不是依赖浏览器。就像,您在一个大的父容器上侦听mousedown + mouseup事件,使用$()。offset()获取所有可单击对象的坐标,然后进行数学运算以查看鼠标坐标是否位于可单击对象上。 / p>

答案 1 :(得分:0)

我找到了document.elementFromPoint的答案,该答案很好用,并且所有现代浏览器都支持。
单击overlay div后,我将隐藏Overlay,并检查鼠标事件位置上哪些元素位于overlay下。
我使用MouseEvent.clientXMouseEvent.clientYdocument.elementFromPoint来确定元素。

$(document).ready(function(){
	$('#group').on('click', function(evt){
		console.log('group');
	});
	$('#overlay').on('click', function(evt){
		console.log('cover');
		$(this).css('display', 'none');
		var element = document.elementFromPoint(evt.clientX, evt.clientY);
		$(this).css('display', 'block');
		$(element).trigger('click');
	});
	$('.item').on('click', function(evt){
		console.log('item-' + $(this).html());
		evt.stopPropagation()
	});
});
#group {
	width: 400px;
	height: 400px;
	position: relative;
	background-color: #eee;
}

#overlay {
	position: absolute;
	top: 50px;
	left: 50px;
	width: 250px;
	height: 250px;
	background-color: #000;
	opacity: 0.2;
	z-index: 10;
}

.item {
	position: absolute;
	width: 150px;
	height: 150px;
	font-size: 4rem;
	line-height: 140px;
	text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="overlay"></div>
<div id="group">
	<div class="item" style="top: 60px; left: 60px; background-color: #fcc;">A</div>
	<div class="item" style="top: 170px; left: 170px; background-color: #cfc; transform: rotateZ(45deg);">B</div>
</div>