大佬教程收集整理的这篇文章主要介绍了单击 SVG 元素会停止触发关键事件,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在制作一款游戏,使用 PIXI 制作图形,使用 Mithril 制作一些 UI 元素。我为各种输入创建事件侦听器(WASD 用于移动,鼠标单击用于操作)。我将 SVG 渲染为 UI 的一部分(带有
我不能简单地关闭与元素的交互,因为我需要能够将事件侦听器附加到 SVG 中的某些元素。我该如何解决这种“重新聚焦”的行为?奇怪的是,我也无法在单击 svg 时触发 onclick(在将 onclick 函数传递给
您的 SVG 被加载到
在一个上下文中发生的事件对另一个上下文是不可见的。这是故意的,您不希望页面上的随机广告能够读取在其嵌入器中输入的所有内容,其他方式也类似。
所以这里的简单解决方案是将您的 SVG 作为内联元素直接附加到主文档中:
onkeydown = (evt) => {
evt.preventDefault();
console.log( "pressed",evt.key );
}
Press any key or click on the rect<br>
<svg viewBox="0 0 100 100" width="100">
<rect fill="green" width="100" height="100"/>
<script>
document.querySELEctor("rect")
.addEventListener("click",(evt) =>
evt.target.setAttribute("fill","#" + ((Math.random()*0xFFFFF)|0) )
);
</script>
</svg>
如果您的 svg 图像和您的文档共享同一来源,您甚至可以从主文档访问
document.querySELEctor("object").addEventListener("load",(evt) => {
const doc = evt.target.contentDocument;
// add your event here
doc.addEventListener("keydown",handler);
});
Outsourced example 因为 StackSnippet 的空域 iframe 不能是同源的...
对于跨源文档,更复杂的方法是在两个上下文之间创建一个枢纽,并让另一方知道事件何时发生。
有一个 proposal going which should allow this,虽然它已经很久没有更新了,它更像是将 Web-Workers 中的 OffscreenCanvas 作为一个用例。但是 last update 的情况可以让希望这种情况也能得到处理。
I wrote an hackish implementation 大致基于最后一个提议,这里是一个使用示例:
const svg_content = `
<svg viewBox="0 0 100 100" width="100" xmlns="http://www.w3.org/2000/svg">
<rect fill="green" width="100" height="100"/>
<!-- load the script from both sides
note that here we load the "cross-origin" version,because StackSnippet's null-origined iframes make this object cross-origin...
-->
<script href="https://cdn.jsdelivr.net/gh/Kaiido/EventPort.js@cross-origin/EventPort.js"/>
<script>
document.querySELEctor("rect")
.addEventListener("click","#" + ((Math.random()*0xFFFFF)|0) )
);
// "parent" will listen to Events firing on "window"
const eventPort = window.createEventPort();
parent.postmessage( eventPort,"*",[eventPort] );
<\/script>
</svg>
`;
document.querySELEctor("object")
.data = URl.createObjectURL( new Blob( [ svg_content ],{ type: "image/svg+xml" } ) );
// we wait for the SVG document to send our EventPort object
window.addEventListener("message",(evt) => {
const eventPort = evt.eventPorts[ 0 ];
// now we can listen to the events occuring there
eventPort.addEventListener( "keydown",(evt) => {
console.log( "pressed in svg document",evt.key );
});
eventPort.addEventListener( "click",(evt) => {
console.log( "clicked in svg document" );
});
});
addEventListener("keydown",(evt) => {
console.log( "pressed in main document",evt.key );
})
<!-- load the script from both sides -->
<script src="https://Kaiido.github.io/EventPort.js/EventPort.js"></script>
Press any key or click on the rect<br>
<object></object>
但实际上,我的脚本很黑,我写它只是作为概念证明来帮助更好地设计可能的 API,并且因为它覆盖了很多全局变量,所以它可以很好地破坏页面上的其他内容。
所以如果可以的话,走简单的路:内联你的 svg。
以上是大佬教程为你收集整理的单击 SVG 元素会停止触发关键事件全部内容,希望文章能够帮你解决单击 SVG 元素会停止触发关键事件所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。