Silence 主題暗黑模式根據瀏覽器配置,以及切換頁面閃白屏的問題處理

kingron發表於2024-06-22

最近使用 Silence v3.0.0-rc2 主題遇到兩個偏好問題(感謝作者提供了這麼好用的主題),記錄下處理的過程。


暗黑/亮色模式跟隨瀏覽器的主題切換

由於主題當前支援的配置項 auto 是根據時間定的,而不是根據瀏覽器的配置來的,而我個人偏向於跟隨瀏覽器的配置來自動設定,於是用 js 先判斷瀏覽器的配置,再將模式配置到 slience 中,具體如下:
在頁尾 HTML 程式碼中的配置項下面加入:

  // 判斷當前瀏覽器的模式是否為 light
  const themeMedia = window.matchMedia("(prefers-color-scheme: light)");

  // 根據瀏覽器的配置設定主題
  if (themeMedia.matches) {
      window.$silence.defaultMode = 'light';

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

暗黑模式下切換頁面閃白屏問題

暗黑模式下,頁面的切換,比如從主頁跳轉到文章詳情頁,或是從文章詳情頁面跳到主頁,頁面都會先閃一下白屏,然後再恢復成暗黑的模式,仔細看了下 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
}

果然就不閃白屏了,但是在亮色模式下還是存在,恢復成原來的程式碼似乎要好一些。
為了讓點選切換主題時也能達到這個效果,這裡也可以在配置中加入對主題切換這一操作的監聽,每當主題發生變化時就相應的更改 --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

相關文章