Loading

Silence 主题暗黑模式根据浏览器配置,以及切换页面闪白屏的问题处理

最近使用 Silence v3.0.0-rc2 主题遇到两个偏好问题(感谢作者提供了这么好用的主题),记录下处理的过程。


暗黑/亮色模式跟随浏览器的主题切换

由于主题当前支持的配置项 auto 是根据时间定的,而不是根据浏览器的配置来的,而我个人偏向于跟随浏览器的配置来自动设置,于是用 js 先判断浏览器的配置,再将模式配置到 slience 中,具体如下:
在页脚 HTML 代码中的配置项下面加入:

  // 判断当前浏览器的模式是否为 light
  const themeMedia = window.matchMedia("(prefers-color-scheme: dark)");

  // 根据浏览器的配置设置主题
  if (themeMedia.matches) {
      window.$silence.defaultMode = 'dark';

  } else {
      window.$silence.defaultMode = 'light';
  }

也可以加入监听浏览器的模式变更事件,让页面自动变化:

// 记录是否被手动设置过
let manualSet = false;

// 监听
themeMedia.addEventListener('change', function() {
    if (manualSet) {
      // 如果有被手动设置过则不处理
      return
    }
    document.querySelector('.mode').click();
    manualSet = false;
  })

// 监听点击切换模式的事件
// 需要放在 slience 主题 js 文件加载之后
document.querySelector('.mode').addEventListener('click', function () {
	manualSet = true
})


暗黑模式下切换页面闪白屏问题

暗黑模式下,页面的切换,比如从主页跳转到文章详情页,或是从文章详情页面跳到主页,页面都会先闪一下白屏,然后再恢复成暗黑的模式,仔细看了下 CSS 定义中 root 的定义:

:root {
    --loading-bg-color: #fff
}

:root[mode=light] {
	...
    --loading-bg-color: #fff
}

:root[mode=dark] {
	...
    --loading-bg-color: #222
}

推测浏览器渲染应该是先渲染了 root 的样式,再渲染的 root[mode=dark] 的样式,于是将 root 的定义改为暗黑的样式:

:root {
    --loading-bg-color: #222
}

果然就不闪白屏了,但是在亮色模式下还是存在,恢复成原来的代码似乎要好一些。为此可以使用 CSS 的条件判断来配置,如果是亮色的话就使用亮色的定义,否则使用暗黑模式的定义,默认定义为亮色:

@media (prefers-color-scheme: dark) {
    :root {
        --loading-bg-color: #222
    }
}

@media (prefers-color-scheme: light) {
    :root {
        --loading-bg-color: #fff
    }
}

@media (prefers-color-scheme: no-preference) {
    :root {
        --loading-bg-color: #fff
    }
}

为了让点击切换主题时也能达到这个效果,这里也可以在配置中加入对主题切换这一操作的监听,每当主题发生变化时就相应的更改 --loading-bg-color 的值,具体如下:
也是在页脚 HTML 代码中的配置项下面加入:

  // 在主题切换时更新 loading-bg-color 的值  
  const root = document.querySelector(':root');

  let mode;
  function resetRootBgColor(mutationsList, observer) {
    let currentMode = $('html').attr('mode');
    if (mode === currentMode) {
        return
    } else {
        mode = currentMode;
    }
    if (currentMode === 'dark') {
      root.style.setProperty('--loading-bg-color', '#222');
    } else {
      root.style.setProperty('--loading-bg-color', '#fff');
    }
  }

  // 加入对主题切换事件的监听
  const mutationObserver = new MutationObserver(resetRootBgColor);
  mutationObserver.observe($('html')[0], { attributes: true });

参考

  1. JS 修改 CSS 变量 - 掘金
  2. WordPress在页面刷新时,因为黑白模式,导致页面闪白或者闪黑问题的解决-ExeHub
  3. 前端判断当前系统主题_浏览器判断当前 theme-CSDN博客
  4. JS监听主题是否为黑暗模式_@media (prefers-color-scheme: light)-CSDN博客
posted @ 2024-06-22 10:33  kingron  阅读(25)  评论(0编辑  收藏  举报