DarkReader API 很早之前用的客户端暗色插件现在支持服务端调用了 DarkReader API 那么正好写一个设置来支持切换深浅色模式,以及持久化用户设置。DarkReader 真的非常方便,理论上默认设置都能很好自动渲染网页生成对应的 CSS,如果有不正常的地方自己微调一下就行。
Setting Page 首先得有一个开关或者设置,这里我选择自己写了一个 Setting 用于存储用户数据,还有保存到 localStorage 之类的的( ) 这里初始化了一个按键的开关,作为被绑定的载体。
Toggle 1 2 3 4 5 6 7 8 <div class ="setting-item" > <label for ="theme-toggle" class ="setting-label" > <strong > Dark Mode</strong > :</label > <span class ="setting-description" > Toggle the dark theme. It will sync with your system theme settings the first time.</span > <label class ="switch" > <input type ="checkbox" id ="theme-toggle" > <span class ="slider round" > </span > </label > </div >
JavaScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 window .onload = function ( ) { const cookieStatus = localStorage .getItem ('allowCookies' ) === 'true' ; const themeStatus = localStorage .getItem ('darkMode' ) === 'true' ; document .getElementById ('cookie-toggle' ).checked = cookieStatus; document .getElementById ('theme-toggle' ).checked = themeStatus; const darkModeStatus = localStorage .getItem ('darkMode' ); if (darkModeStatus !== null ) { if (darkModeStatus === 'true' ) { DarkReader .enable ({ brightness : 100 , contrast : 100 , sepia : 0 }); } else { DarkReader .disable (); } } else { DarkReader .auto ({ brightness : 100 , contrast : 90 , sepia : 10 }); localStorage .setItem ('darkMode' , DarkReader .isEnabled ().toString ()); } }; document .getElementById ('theme-toggle' ).addEventListener ('change' , function ( ) { const isDarkMode = this .checked ; localStorage .setItem ('darkMode' , isDarkMode.toString ()); if (isDarkMode) { DarkReader .enable ({ brightness : 100 , contrast : 100 , sepia : 0 }); } else { DarkReader .disable (); } });
上面的 JS 调用的 window.onload 只是为了设置界面可以正常生效,并且持久化和每次自动从 localStorage 加载按键信息所用的,具体的全局设置可以参考这样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 <!DOCTYPE html > <html lang ="{{ config.language }}" > <head > {% include "_partial/head.swig" %} <title > {% block title %}{% endblock %}</title > </head > <body > <script > (function ( ) { const darkModeSetting = localStorage .getItem ('darkMode' ); if (darkModeSetting === 'true' ) { DarkReader .enable ({ brightness : 100 , contrast : 100 , sepia : 0 }); } else if (darkModeSetting === 'false' ) { DarkReader .disable (); } else { DarkReader .auto ({ brightness : 100 , contrast : 90 , sepia : 10 }); } const isEnabled = DarkReader .isEnabled (); localStorage .setItem ('darkMode' , isEnabled.toString ()); })(); </script > <div class ="container" > {% include "_partial/header.swig" %} <div class ="container-inner" style ="display:none;" > <main class ="main" id ="main" > <div class ="main-wrapper" > {% block main %} {% endblock %} </div > </main > {% include "./_partial/footer.swig" %} </div > {% include "./_partial/tagcloud.swig" %} </div > {% include "_partial/_feature/common.swig" %} </body > </html >
这里我之前踩过坑,那就是在最开始调用这个 JS 会导致加载过早, 导致后面渲染出来的页面完全没有被应用深色模式,如果用 window.onload 会导致深色模式的一瞬间加载的时候实际上是浅色主题,等加载完后才执行的 API, 所以你应该把这段 JS 塞在 _layout.swig 或者你使用的框架的合适地方, 比如整体 Web Body( )