You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Astro/Svelte组件无法访问document元素的问题及解决方法

解决Astro/Svelte主题切换组件中的“document is not defined”错误

我编写了一个实现主题切换的Astro/Svelte组件,点击按钮时能正常打印document.documentElement.classList,但在响应式代码块中操作document时,出现了**"document is not defined"**的错误。

原组件代码如下:

<script lang="ts">
  let theme = localStorage.getItem("theme") ?? "light";
  const handleClick = () => {
    theme = (theme === "light" ? "dark" : "light");    
    console.log('classlist',document.documentElement.classList);    
  };
  $:{
    if (theme === "dark") {
      document!.documentElement.classList.add("dark");
    } else {
      document!.documentElement.classList.remove("dark");
    }
    localStorage.setItem("theme", theme);
  }
</script>

<button on:click={handleClick}>{theme === "light" ? "🌙" : "🌞"}</button>

感谢@H.B提供的解决方案,通过引入Svelte的onMount钩子,确保仅在组件挂载到客户端DOM后再执行操作document的代码,避免了服务端渲染时找不到document的问题。修改后的代码如下:

<script lang="ts">
  import { onMount } from "svelte";
  let theme = localStorage.getItem("theme") ?? "light";  
  let flag = false;
  onMount(()=>{
    flag = true
  }) 
  $: if (flag) {
    if ( theme === 'dark') {
      document!.documentElement.classList.add("dark");
    } else {
      document!.documentElement.classList.remove("dark");
    }
    localStorage.setItem("theme", theme);
  }
  const handleClick = () => {
    theme = (theme === "light" ? "dark" : "light");    
    console.log('classlist',document.documentElement.classList);    
  }; 
</script>

<button on:click={handleClick}>{theme === "light" ? "🌙" : "🌞"}</button>

修改后的代码可正常运行,核心思路是利用onMount仅在客户端触发的特性,通过flag变量控制响应式代码块的执行时机,确保操作document时环境已存在该对象。

内容的提问来源于stack exchange,提问作者Juan Martín Jaimes Mendoza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:06:19