theme.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. (function () {
  2. const supportedThemes = ['dark', 'light'];
  3. const defaultTheme = 'light';
  4. const storageKey = 'bex_preferred_theme';
  5. let autoInitSkipped = false;
  6. function normalizeTheme(theme) {
  7. return supportedThemes.includes(theme) ? theme : '';
  8. }
  9. function getCurrentTheme() {
  10. const urlParams = new URLSearchParams(window.location.search);
  11. const themeFromUrl = normalizeTheme(urlParams.get('theme'));
  12. if (themeFromUrl) return themeFromUrl;
  13. if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
  14. return 'light';
  15. }
  16. return defaultTheme;
  17. }
  18. function setTheme(theme) {
  19. const nextTheme = normalizeTheme(theme);
  20. if (!nextTheme) return;
  21. const root = document.documentElement;
  22. const body = document.body;
  23. const container = document.querySelector('.container');
  24. if (root) {
  25. root.classList.remove('theme-dark', 'theme-light');
  26. root.classList.add('theme-' + nextTheme);
  27. }
  28. if (body) {
  29. body.classList.remove('theme-dark', 'theme-light');
  30. body.classList.add('theme-' + nextTheme);
  31. }
  32. if (container) {
  33. container.classList.remove('theme-dark', 'theme-light');
  34. container.classList.add('theme-' + nextTheme);
  35. }
  36. // try {
  37. // localStorage.setItem(storageKey, nextTheme);
  38. // } catch (e) {}
  39. window.dispatchEvent(new CustomEvent('themechange', { detail: { theme: nextTheme } }));
  40. }
  41. const BEXTheme = {
  42. supportedThemes: supportedThemes,
  43. defaultTheme: defaultTheme,
  44. getCurrentTheme: getCurrentTheme,
  45. setTheme: setTheme,
  46. toggleTheme: function () {
  47. const nextTheme = getCurrentTheme() === 'dark' ? 'light' : 'dark';
  48. setTheme(nextTheme);
  49. return nextTheme;
  50. },
  51. init: function () {
  52. setTheme(getCurrentTheme());
  53. },
  54. skipAutoInit: function () {
  55. autoInitSkipped = true;
  56. }
  57. };
  58. window.BEXTheme = BEXTheme;
  59. if (document.readyState === 'loading') {
  60. document.addEventListener('DOMContentLoaded', function () {
  61. if (!autoInitSkipped) {
  62. BEXTheme.init();
  63. }
  64. });
  65. } else if (!autoInitSkipped) {
  66. BEXTheme.init();
  67. }
  68. })();