在Svelte中从深色模式切换到浅色模式时对变化做出响应。

huangapple go评论62阅读模式
英文:

Reacting to changes when switching from dark to light mode in Svelte

问题

我试图在主题从深色切换到浅色时显示特定消息。为了确定主题是浅色还是深色,我查看 document.documentElement.classList 并检查它是否包含 dark,即类似 document.documentElement.classList.contains("dark") 的内容。

然而,当我尝试在脚本中以响应式方式绑定一个值时:

<script>
$: isDarkMode = document.documentElement.classList.contains("dark")
</script>

我收到了一个500内部错误。我不知道错误的来源是什么。

下面我提供了所有的代码,如果它在任何方面有帮助的话。

<script lang="ts">
  function toggleTheme() {
    if (document.documentElement.classList.contains("dark")) {
      document.documentElement.classList.remove("dark");
    } else {
      document.documentElement.classList.add("dark");
    }
  }

  $: isDarkMode = document.documentElement.classList.contains("dark");
</script>

<button on:click={toggleTheme}>切换主题</button>

{#if isDarkMode}
  <p>欢迎来到黑暗面!</p>
{:else}
  <p>请检查您的健康</p>
{/if}

注意:toggleTheme 按预期工作。起初,我认为问题与访问 document 有关,但似乎并非如此。

是否有人知道是什么导致了内部错误以及如何修复它?感谢您的帮助。

英文:

I am trying to display a certain message when theme changes from dark to light. To determine whether theme is light or dark, I look at document.documentElement.classList and check if it contains dark, i.e. something like document.documentElement.classList.contains(&quot;dark&quot;).

However, when I try to bind a value reactively in the script:

&lt;script&gt;
$: isDarkMode = document.documentElement.classList.contains(&quot;dark&quot;)
&lt;/script&gt;

I receive a 500 internal error. I do not know what could be the source of the error.

Below I provide all the code, should it prove to be helpful in any way.

&lt;script lang=&quot;ts&quot;&gt;
  function toggleTheme() {
    if (document.documentElement.classList.contains(&quot;dark&quot;)) {
      document.documentElement.classList.remove(&quot;dark&quot;);
    } else {
      document.documentElement.classList.add(&quot;dark&quot;);
    }
  }

  $: isDarkMode = document.documentElement.classList.contains(&quot;dark&quot;);
&lt;/script&gt;

&lt;button on:click={toggleTheme}&gt;Change theme&lt;/button&gt;

{#if isDarkMode}
  &lt;p&gt;Welcome to the dark side!&lt;/p&gt;
{:else}
  &lt;p&gt;Please have your health checked&lt;/p&gt;
{/if}

Note: toggleTheme works as expected. In the beginning, I assumed the problem had something to do with accessing the document, but that does not seem to be the case.

Does someone know what is causing the internal error and how to fix it? Thank you for the help.

答案1

得分: 1

问题可能在于访问文档。在函数内部的使用并不重要,因为它只能在文档存在的浏览器中触发。如果存在服务器端渲染,任何在初始渲染期间发生的使用都会引发错误。

逻辑似乎相反,响应性将无法工作,因为 document 不是响应式的。可以使用本地标志,根据该标志设置类别。本地值将是响应式的,因为它在组件中声明。

您可以以不同的方式防范服务器端渲染问题,如果您使用 SvelteKit,可以使用 browser 标志。例如:

<script>
  import { browser } from '$app/environment';

  let isDarkMode = true;
  $: if (browser) {
    document.documentElement.classList.toggle('dark', isDarkMode);
  }
</script>
<button on:click={() => isDarkMode = !isDarkMode}>Change theme</button>

如果不使用 SvelteKit,您可以在 onMount 中设置某些标志。

英文:

The problem probably is accessing the document. Usage within the function does not matter because that can only be triggered in the browser where the document exists. If there is server-side rendering, any usage that happens during initial rendering will cause errors.

The logic seems backward and the reactivity would not work, as document is not reactive. Would instead use a local flag and set the class depending on that instead. The local value will be reactive as it is declared in the component.

You can guard against SSR issues in different ways, if you are using SvelteKit you can use the browser flag. E.g.

&lt;script&gt;
  import { browser } from &#39;$app/environment&#39;;

  let isDarkMode = true;
  $: if (browser) {
    document.documentElement.classList.toggle(&#39;dark&#39;, isDarkMode);
  }
&lt;/script&gt;
&lt;button on:click={() =&gt; isDarkMode = !isDarkMode}&gt;Change theme&lt;/button&gt;

If not using SvelteKit, you could e.g. set some flag to true in onMount.

huangapple
  • 本文由 发表于 2023年7月12日 23:50:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672409.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定