我正在尝试制作一个包含画布的Svelte组件,该组件将在其中显示经脚本编写的webgl应用程序。在传统的html中,它需要以下设置:
<script>
var canv = document.getElementById('canvas');
var Module = { canvas: canv };
</script>
<script src="index.js"></src>
我最接近的是以下几句话:
<script>
let canv;
let Module = { canvas: canv };
</script>
<svelte:head>
<script src="index.js"></src>
</svelte:head>
<canvas bind:this={canv}></canvas>
哪个确实加载了模块,但index.js未能初始化并出现某些错误:
exception thrown: TypeError: eventHandler.target is null,registerOrRemoveHandler
基本上是index.js无法看到Module
-如果我根本不初始化Module
,此错误仍然相同。
我知道我可以使用MODULARIZE
编译器选项(我还没有研究过),但是由于它是一个webgl应用程序,所以我宁愿让它像传统html一样在加载时运行可以专注于C ++,而无需自己设置管道。
正确的做法是什么?
这里发生了几件事。
首先,组件等效于JavaScript模块,这意味着在组件内部声明的任何变量都在该组件本地。如果需要Module
全局可用,则应在window
上进行设置:
window.Module = { canvas: canv };
第二,您每次使用bind:this
时,都需要等到实际安装组件后再进行操作。组件<script>
中的代码在创建任何DOM之前运行(因为它通常determines创建什么DOM)。
在这种情况下,请尝试使用onMount
:
<script>
import { onMount } from 'svelte';
let canv;
onMount(() => {
window.Module = { canvas: canv };
});
</script>
<svelte:head>
<script src="index.js"></src>
</svelte:head>
<canvas bind:this={canv}></canvas>