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>
答案 0 :(得分:1)
将{css属性pointer-events: none;
添加到#other-div
会让点击或其他指针相关事件通过div并到达画布和容器
#other-div {
z-index: 1;
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
请参阅Fiddle 1
如果这不合适,因为您需要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');
});
当投币器收到点击时,它也触发了对未决画布的点击:$('#canvas').click();
请注意,当点击最终到达画布时,事件必须停止传播,否则它将冒泡并同时点击#other-div
和#container
导致无限循环。这就是你e.stopImmediatePropagation();
请参阅Fiddle 2
答案 1 :(得分:1)
当您点击outer-div
并让canvas
听取此活动时,您可以触发custom event:
$('#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");
});
&#13;
#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);
}
&#13;
<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>
&#13;
答案 2 :(得分:0)
您可以通过修补Element原型来使用动态方法:
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'));
&#13;
#other-div {
z-index: 1;
position: absolute;
top: 0;
left: 0;
}
#canvas {
z-index: 0;
position: absolute;
top: 0;
left: 0;
}
&#13;
<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>
&#13;