Vite+Svelte项目中SVG.js的addTo()方法找不到目标DOM的问题
在Vite+Svelte中正确实现SVG.js的解决方案
问题根源
你遇到的TypeError: Cannot read properties of null (reading 'put'),本质是SVG.js的addTo()方法找不到目标DOM元素。而DOMContentLoaded事件在Svelte中不生效,是因为Svelte组件的渲染时机晚于该事件触发时机——当组件开始执行代码时,DOMContentLoaded已经触发完毕,回调自然不会执行。
正确实现步骤
1. 安装SVG.js
先确保已安装依赖:
npm install @svgdotjs/svg.js # 或用pnpm/yarn pnpm add @svgdotjs/svg.js yarn add @svgdotjs/svg.js
2. 方案一:onMount生命周期 + bind:this
这是最稳妥的方式,利用Svelte的onMount确保组件挂载后再初始化SVG.js,同时通过bind:this直接获取目标DOM元素:
<script> import { onMount } from 'svelte'; import { SVG } from '@svgdotjs/svg.js'; // 绑定容器DOM元素 let svgContainer; // 存储SVG实例,方便后续操作与销毁 let draw; onMount(() => { // 初始化SVG并添加到容器 draw = SVG().addTo(svgContainer).size(300, 300); // 示例:绘制红色矩形 draw.rect(100, 100).fill('#ff4444').move(50, 50); // 组件销毁时清理SVG实例,避免内存泄漏 return () => { draw?.remove(); }; }); </script> <!-- 承载SVG的容器 --> <div bind:this={svgContainer}></div>
3. 方案二:响应式语句监听DOM元素
利用Svelte的响应式特性,当bind:this绑定的DOM元素存在时自动初始化SVG.js:
<script> import { SVG } from '@svgdotjs/svg.js'; let svgContainer; let draw; // 当容器DOM存在时初始化SVG $: if (svgContainer) { draw = SVG().addTo(svgContainer).size(300, 300); // 示例:绘制蓝色圆形 draw.circle(80).fill('#33b5e5').center(150, 150); } // 组件卸载时清理SVG实例 $: if (!svgContainer && draw) { draw.remove(); } </script> <div bind:this={svgContainer}></div>
关键注意事项
- 不要用
document.getElementById获取DOM:组件渲染前,目标元素尚未挂载到页面,会返回null,bind:this是Svelte提供的可靠获取组件内DOM的方式。 - 必须清理SVG实例:组件销毁时调用
draw.remove(),避免残留DOM节点与内存泄漏。
内容的提问来源于stack exchange,提问作者KYUNGMIN CHOI
相关产品推荐
相关产品推荐

