网站白天or黑夜切换在重新加载时闪烁白色背景的解决思路

一般网站主题设置的白天or黑夜通过js来切换开关,并且通过cookie值来存储当前是白天or黑夜,但是如果网站访问慢的时候,会导致黑夜的时候,网页还没有读取到cookie值的内容,便已经加载了css里面的白色背景,然后读取cookie后再迅速切换到了黑色背景

此时便导致了出现闪烁白色背景的现象

于是通过下面的一篇文章思路尝试这样的解决,下面的文章提到(内部放置一个小的< script> 标签来阻止页面呈现文档的< head>)但是尝试多次,发现还是未能解决,但是白天or黑夜的设置确实已经通过js存储到了localStorage值里面,于是……

在head之前添加了

  1. <script>// Render blocking JS:
  2. if (localStorage.theme) document.documentElement.setAttribute("data-theme", localStorage.theme);
  3. </script>

让data-theme来获取localStorage.theme的白天or黑夜值

然后在把主题里面的css白天和黑夜的背景颜色通过 :root 选择器来赋值,也就是背景颜色会以var(--bg-body)来设置背景色,但是此时var(--bg-body)是未知的颜色

因此加了这一段

  1. [data-theme="0"] {
  2. --bg-body: #f6f8fb;
  3. --bg-secondary: #fff;
  4. }
  5. [data-theme="1"] {
  6. --bg-body: #192039;
  7. --bg-secondary: #1f2745;
  8. }

当data-theme的为白天或者黑夜的时候,便开始给var(--bg-body)赋予了颜色值,从而在继续加载css样式的时候才会显示var(--bg-body)已经指定的颜色值,这样就没有了黑夜展示之前的闪烁白色背景了,因为黑夜模式下,白色背景是不存在

但是部分主题只是设置了毕竟明显大部分位置,比如背景,框架背景,头部背景,保证了这部分地方是解决了闪烁白色背景的问题,但是实际上其他的元素,区域还是会有白色的闪烁,只是可能极为短暂,容易忽视掉……

看看以下原文吧

=====================================

以下为转载文章的全文

始于问题:

我正在尝试在我的应用程序中添加此黑暗模式功能.它使用本地存储来存储用户的首选项,以备将来使用.所以现在的问题是,启用暗模式后,由于某种原因重新加载了页面,相同的是用户有意重新加载页面或提交表单,然后在页面变成白色之前,整个页面都有白色背景闪烁黑暗的.它只停留了不到一秒的时间.看起来并不专业.

尚未找到任何解决方案.所以请帮帮我.

PS.下面的代码段在SO中无法正常工作,因为该代码包含 localStorage 对象

  1. const toggleSwitch = document.querySelector('#dark-mode-button input[type="checkbox"]');
  2. const currentTheme = localStorage.getItem('theme');
  3. if (currentTheme) {
  4. document.documentElement.setAttribute('data-theme', currentTheme);
  5. if (currentTheme === 'dark') {
  6. toggleSwitch.checked = true;
  7. }
  8. }
  9. function switchTheme(e) {
  10. if (e.target.checked) {
  11. document.documentElement.setAttribute('data-theme', 'dark');
  12. localStorage.setItem('theme', 'dark');
  13. }else {
  14. document.documentElement.setAttribute('data-theme', 'light');
  15. localStorage.setItem('theme', 'light');
  16. }
  17. }
  18. toggleSwitch.addEventListener('change', switchTheme, false);

css样式如下

  1. :root {
  2. --primary-color: #495057;
  3. --bg-color-primary: #F5F5F5;
  4. }
  5. body{
  6. background-color: var(--bg-color-primary);
  7. }
  8. [data-theme="dark"] {
  9. --primary-color: #8899A6;
  10. --bg-color-primary: #15202B;
  11. }
  12. table {
  13. font-family: arial, sans-serif;
  14. border-collapse: collapse;
  15. width: 100%;
  16. background-color: #fff;
  17. }
  18. td, th {
  19. border: 1px solid #dddddd;
  20. text-align: left;
  21. padding: 8px;
  22. }

html页面代码

  1. <div id="dark-mode-button">
  2. <input id="chck" type="checkbox">Dark Mode
  3. <label for="chck" class="check-trail">
  4. <span class="check-handler"></span>
  5. </label>
  6. </div>
  7. <table class="table">
  8. <thead>
  9. <tr>
  10. <th>Header 1</th>
  11. <th>Header 2</th>
  12. <th>Header 3</th>
  13. </tr>
  14. </thead>
  15. <tbody>
  16. <tr>
  17. <td>Alfreds Futterkiste</td>
  18. <td>Maria Anders</td>
  19. <td>Germany</td>
  20. </tr>
  21. </tbody>

推荐答案

最好在内部放置一个小的< script> 标签来阻止页面呈现文档的< head> .这样,渲染器应停止调用JavaScript解释器,将 data-theme 属性分配给< html> ,然后在左侧继续.试试看:

将此< script> 放置在< head> 内-甚至在< link> 或< style>之前

  1. <head>
  2. <!-- meta, title etc... -->
  3. <script>
  4. // Render blocking JS:
  5. if (localStorage.theme) document.documentElement.setAttribute("data-theme", localStorage.theme);
  6. </script>
  7. <!-- link, style, etc... -->
  8. </head>

然后,在结束标记之前 之前,以非渲染阻止方式使用所有其他脚本

  1. <!-- other <script> tags here -->
  2. <script>
  3. const toggleSwitch = document.querySelector('#dark-mode-button input[type="checkbox"]');
  4. if (localStorage.theme) {
  5. toggleSwitch.checked = localStorage.theme === "dark";
  6. }
  7. function switchTheme(e) {
  8. const theme = e.target.checked ? "dark" : "light";
  9. document.documentElement.setAttribute("data-theme", theme);
  10. localStorage.theme = theme;
  11. }
  12. toggleSwitch.addEventListener("change", switchTheme);
  13. </script>
  14. <!-- Closing </body> goes here -->
文章由官网发布,如若转载,请注明出处:https://www.veimoz.com/1177
1 条评论
2.7k

发表评论

!