javascript Astro:使内联脚本与呈现的组件交互

nom7f22z  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(128)

所以,我有一个用于切换黑暗模式的脚本。该脚本将主题首选项保存到本地存储并相应地将修改应用到DOM。html中的默认主题是黑暗的。当在本地存储中保存白色主题首选项时,DOM在渲染时被修改为**烦人的 Flink **。为了解决这个问题,我遵循了this指南,我尝试在页面加载之前执行主题脚本。下面是我当前Layout.astro的示例:

<head>
  <script is:inline>
    // The configured mode is stored in local storage
    const isDarkMode = localStorage.getItem('darkMode');

    // Set theme to 'dark' if darkMode = 'true'
    const theme = isDarkMode === 'true' ? 'dark' : '';

    // Put dark class on html tag to enable dark mode
    document.querySelector("html").className = theme;
   
    // Change other elements accordingly
    document.querySelectorAll(".my").className = theme;

  </script>
...
</head>

样式是在一个.css文件中定义的。

<Layout>
  <Navbar navLinks={navLinks} />

  <Hero />

  <Bar />

  <Foo />

  <Contacts />
</Layout>

问题是我的.my-element元素分散在所有组件中(即NavbarHero等)。由于内联脚本是在Layout.astro中定义的,因此它无法访问组件内部的.my-element元素。如果我删除is:inline,它可以工作,但当然我会回到起点。
有什么方法可以解决这个问题吗?理想情况下,我需要在应用样式表之前修改与元素关联的类。

jchrr9hc

jchrr9hc1#

在这种情况下,你可能想改变图标组件的工作方式,你可以使用html元素上设置的相同类名来改变它们的样式。
我不确定你的样式现在看起来是什么样的,但是如果它们是像.icon.light { ... }这样的东西,它们可能会变成.light .icon { ... }(第二个中的空间很重要!)
此外,如果你使用Astro的scoped CSS编写这些样式,你需要明确地说light类来自icon组件之外,方法是在html元素的类周围使用:global()

---
// Icon.Astro
---
<svg class="icon">...</svg>

<style>
.icon {
  /* dark styles */
}

:global(.light) .icon {
  /* light styles */
}
</style>

相关问题