index.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. const PERSISTENCE_KEY = 'darkmode:color-scheme'
  2. window.addEventListener('load', async () => {
  3. const menu = document.getElementById('themeMenu')
  4. const $icon = document.getElementById('navbar-theme-icon-svg')
  5. if (menu == null || $icon == null) return
  6. const btns = menu.getElementsByTagName('a')
  7. const iconMap = Array.from(btns).reduce((map, btn) => {
  8. const $img = btn.getElementsByTagName('img')[0]
  9. map[btn.dataset.scheme] = $img.src
  10. return map
  11. }, {})
  12. function loadScheme() {
  13. return localStorage.getItem(PERSISTENCE_KEY) || "system"
  14. }
  15. function saveScheme(scheme) {
  16. localStorage.setItem(PERSISTENCE_KEY, scheme)
  17. }
  18. function getPreferredColorScheme() {
  19. const isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
  20. return isDarkMode ? "dark" : "light";
  21. }
  22. function setScheme(newScheme) {
  23. let theme = newScheme
  24. if (newScheme === 'system') {
  25. theme = getPreferredColorScheme()
  26. }
  27. // set data-theme attribute on html tag
  28. document.querySelector("html").dataset.theme = theme;
  29. // update icon
  30. $icon.src = iconMap[newScheme]
  31. // save preference to local storage
  32. saveScheme(newScheme)
  33. setImages(theme)
  34. }
  35. setScheme(loadScheme())
  36. Array.from(menu.getElementsByTagName('a')).forEach((btn) => {
  37. btn.addEventListener('click', () => {
  38. const { scheme } = btn.dataset
  39. setScheme(scheme)
  40. })
  41. })
  42. })
  43. function setImages(newScheme) {
  44. const els = Array.from(document.getElementsByClassName('logo-holder'));
  45. for (const el of els) {
  46. const light = el.querySelector('.light-logo');
  47. const dark = el.querySelector('.dark-logo');
  48. if (newScheme === "dark" && dark !== null) {
  49. if (light !== null) light.style.display = 'none'
  50. dark.style.display = 'inline'
  51. }
  52. else {
  53. if (light !== null) light.style.display = 'inline'
  54. if (dark !== null) dark.style.display = 'none'
  55. }
  56. }
  57. }