index.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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. }
  34. setScheme(loadScheme())
  35. Array.from(menu.getElementsByTagName('a')).forEach((btn) => {
  36. btn.addEventListener('click', () => {
  37. const { scheme } = btn.dataset
  38. setScheme(scheme)
  39. })
  40. })
  41. })