我想捕获两个图层上的鼠标事件:PIXI的画布和覆盖div。我有以下类型的HTML设置div.overlay
高于canvas.pixi
:
<div class="parent">
<canvas class="pixi"></canvas>
<div class="overlay"></div>
</div>
当canvas
位于顶部时,PIXI交互工作正常,但当画布与div.overlay
重叠时,我无法捕获任何事件。
我发现setTargetElement
似乎让我们为捕获元素定义了DOM元素,我试图像这样使用它:
const renderer = PIXI.autoDetectRenderer(...);
renderer.plugins.interaction.setTargetElement(document.querySelector('.overlay'));
使用此技术,我可以捕获mousemove
个事件,但遗憾的是click
,mousedown
等不起作用。
我还尝试复制div.overlay
上捕获的原始事件,然后重复发送canvas
上的事件,如下所示,但这也不起作用。
document.querySelector('.overlay').addEventListener('mousedown', (e) => {
const eventCopy = document.createEvent('MouseEvents');
eventCopy.initMouseEvent(
e.type, e.bubbles, e.cancelable, e.view,
e.detail, e.pageX || e.layerX,
e.pageY || e.layerY, e.clientX,
e.clientY, e.ctrlKey, e.altKey, e.shiftKey,
e.metaKey, e.button, e.relatedTarget
);
document.querySelector('.pixi').dispatchEvent(eventCopy);
});
有没有办法在重叠的DOM元素上捕获鼠标事件并将事件传递给PIXI?
为什么吗
我想与PIXI元素进行交互,同时能够利用D3的缩放和画笔功能,目前正在重叠的div上进行处理。
更新&amp;代码示例
我设法转发事件,所有但是点击事件都是由PIXI注册的。可以通过重新触发pointerdown
和pointerup
事件来手动触发点击事件。查看https://jsfiddle.net/v3chhhjk/1/
答案 0 :(得分:3)
一种可能的解决方案是捕获父级的所有事件并将其遍历回子元素。像这样。这样做是为了点击,同样适用于mousemove。
function traverseEventToChild(e){
if(e.type="click"){
const eventCopy = document.createEvent('MouseEvents');
eventCopy.initMouseEvent(
e.type, e.bubbles, e.cancelable, e.view,
e.detail, e.pageX || e.layerX,
e.pageY || e.layerY, e.clientX,
e.clientY, e.ctrlKey, e.altKey, e.shiftKey,
e.metaKey, e.button, e.relatedTarget
);
console.log('parent handler');
document.querySelector('.pixi').dispatchEvent(eventCopy);
}
}
function piximousemove(e){
console.log('pixi click');
e.stopPropagation();
}
function overlaymousemove(e){
console.log('overlay click');
}
document.querySelector('.pixi').onclick = piximousemove;
document.querySelector('.overlay').onclick = overlaymousemove;
<div class="parent" id='parent' onclick="traverseEventToChild(event);">
<canvas class="pixi" id='canvas'>pixi</canvas>
<div class="overlay" id='overlay'>overlay</div>
</div>
答案 1 :(得分:1)
如果您只需要通过叠加层传递事件,请使用css pointer-events: none;
更多详情:https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
答案 2 :(得分:1)
问题在于DOM是分层的。 Here's an old issue about the exact same thing。事实证明,你可以通过简单的方式将事件传播给兄弟姐妹,只有父母和孩子。我建议将collection_def {
key: "global_step"
value {
node_list {
value: "global_step:0"
}
}
}
放在w = tf.get_variable("foo_weights", dtype=tf.float32, shape=[1, 1], initializer=tf.zeros_initializer, use_resource=True)
内,然后你可以捕捉它并在冒泡阶段捕捉它,这取决于你是否想要在画布之前或之后处理它们。
我认为下面应该按预期工作。
HTML:
collection_def {
key: "trainable_variables"
value {
bytes_list {
value: "\n\rfoo_weights:0\022\022foo_weights/Assign(\001"
}
}
}
示例JS:
canvas
答案 3 :(得分:0)
我通过克隆事件并重建mouseover
使其适用于mouseout
,mousedown
,mouseup
,click
和click
事件mousedown
和mouseup
事件发生的事件。当从事件层克隆事件时,除click
事件外的所有事件都可以开箱即用,但不会触发单击事件。
所以给出以下HTML结构:
<div id="parent">
<canvas id="pixi"></canvas>
<div id="overlay"></div>
</div>
我听了很多这样的事件:
const overlay = document.getElementById('overlay');
overlay.addEventListener('pointerdown', forwardDown);
overlay.addEventListener('pointerup', forwardUp);
overlay.addEventListener('pointermove', forward);
overlay.addEventListener('pointerover', forward);
overlay.addEventListener('pointerout', forward);
然后转发/克隆事件:
const canvas = document.getElementById('pixi');
let mousedown = false;
const clone = e => new e.constructor(e.type, e);
const forward = (e) => { canvas.dispatchEvent(clone(e)); };
const forwardDown = (e) => { mousedown = true; forward(e); };
const forwardUp = (e) => {
forward(e);
if (mousedown) console.log('It\'s a click!');
mousedown = false;
};
事件也可以在其他地方调度,例如D3可以识别。
演示:https://jsfiddle.net/v3chhhjk/3/
左上角演示了使用PIXI直接捕获事件时的工作原理。右上角显示克隆事件时的问题。左下角显示了一个奇怪的行为,其中重新触发相同的事件实际上使PIXI识别点击事件,最后,右下角。