的jsfiddle:https://jsfiddle.net/uLap7yeq/19/
问题
考虑两个元素,canvas和div,它们位于相同的树深度并具有相同的父级。它们都使用CSS放在相同的位置,但div具有更高的z-index。如何从div中捕获事件并将它们传递给较低的z-index?我必须在画布上执行.dispatchEvent()吗?
编辑:为了澄清,我希望div接收事件,做任何想做的事情,然后将它传递给下一个z-indexed元素。
JSFiddle在线粘贴:
/*
How can I pass the event along to #canvas?
*/
$('#container').on('click', function(e) {
console.log('#container click');
});
$('#canvas').on('click', function(e) {
console.log('#canvas click');
});
$('#other-div').on('click', function(e) {
console.log('#other-div click');
});
#other-div {
z-index: 1;
position: absolute;
top: 0;
left: 0;
}
#canvas {
z-index: 0;
position: absolute;
top: 0;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="other-div">
<p>
Something
</p>
</div>
<canvas id="canvas" width="200" height="200"></canvas>
</div>
将css属性pointer-events: none;
添加到#other-div
将允许点击或其他与指针相关的事件通过div并到达画布和容器
#other-div {
z-index: 1;
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
如果这不合适,因为您需要other-div
也捕获事件(根据您的评论),那么您可以在单击容器时以编程方式触发画布上的事件
$('#container').on('click', function(e) {
console.log('#container click');
$('#canvas').click(); // <------
});
$('#canvas').on('click', function(e) {
e.stopImmediatePropagation(); // <------
console.log('#canvas click');
});
$('#other-div').on('click', function(e) {
console.log('#other-div click');
});
当投币器收到点击时,它也会触发对底层画布的点击:qazxsw poi
请注意,当点击最终击中画布时,事件必须停止传播,否则它将冒泡并击中$('#canvas').click();
和#other-div
,导致无限循环。这就是为什么你有#container
见e.stopImmediatePropagation();
当你点击Fiddle 2并让custom event听这个事件时,你可以触发outer-div
:
canvas
$('#container').on('click', function(e) {
console.log('#container click');
});
$('#canvas').on('click custom', function(e) {
console.log('#canvas click');
});
$('#other-div').on('click', function(e) {
console.log('#other-div click');
$('#canvas').trigger( "custom");
});
#other-div {
z-index: 1;
position: absolute;
top: 0;
left: 0;
background:rgba(255,0,0,0.2);
}
#canvas {
z-index: 0;
position: absolute;
top: 0;
left: 0;
background:rgba(255,255,0,0.2);
}
您可以通过修补Element原型来使用动态方法:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="other-div">
<p>
Something
</p>
</div>
<canvas id="canvas" width="200" height="200"></canvas>
</div>
if (!document.elementsFromPoint) {
document.elementsFromPoint = elementsFromPoint;
}
function elementsFromPoint(x, y) {
var parents = [];
var parent = void 0;
do {
if (parent !== document.elementFromPoint(x, y)) {
parent = document.elementFromPoint(x, y);
parents.push(parent);
parent.style.pointerEvents = 'none';
} else {
parent = false;
}
} while (parent);
parents.forEach(function (parent) {
parent.style.pointerEvents = 'initial';
});
return parents;
}
Element.prototype.makeEventGoThrough = function(eventName) {
$(this).on(eventName, (e) => {
var elements = document.elementsFromPoint(e.clientX, e.clientY);
var children = [].slice.call(this.children);
elements = elements.filter(element => element !== this && !children.find(el => el === element));
elements.forEach(element => $(element).trigger(eventName));
});
}
/*
How can I pass the event along to #canvas?
*/
document.getElementById('other-div').makeEventGoThrough('click');
$('#other-div').on('click', () => console.log('other-div clicked'));
$('#canvas').on('click', () => console.log('canvas clicked'));
#other-div {
z-index: 1;
position: absolute;
top: 0;
left: 0;
}
#canvas {
z-index: 0;
position: absolute;
top: 0;
left: 0;
}