通过 JavaScript 给网站切换夜间模式
最近突发奇想想给博客做个夜间模式。
网络上有很多傻瓜化方法,比如 darkmode.js,但是他的默认样式在我的博客网站上实在是非常糟糕,并且并不能很方便的更改样式。
还有其他方法比如给 <body>
添加 class
再用 css 选择器实现样式的更换。
我注意到了 HTML5 增加了媒体查询和媒体监听器,以及通过 alternate 属性值来控制 css 显示/隐藏的方法,于是就有了下面这个简单的夜间主题控制器。
只需要 2 步即可。
-
添加以下内容到你的网页上的
<head>
元素,darkmode.css 是用于实现夜间模式的外部css文件,注意引入顺序带来的优先级问题。<!-- Darkmode Copyright 2021 YexuanXiao under MIT license --> <link rel="alternate stylesheet preload" as="style" href="darkmode.css" id="darkmode-css"> <script> // init darkmode { const darkmodeCss = document.getElementById('darkmode-css') const media = matchMedia('(prefers-color-scheme: dark)') const time = new Date().getHours() if (media.matches || ((time > 20 || time < 6) && sessionStorage.getItem('darktheme') !== 'false')) { darkmodeCss.rel = 'stylesheet' sessionStorage.setItem('darktheme', 'true') } else if (sessionStorage.getItem('darktheme') === 'true') { darkmodeCss.rel = 'stylesheet' } else { sessionStorage.setItem('darktheme', 'false') } media.addEventListener('change', () => { media.matches ? darkmodeCss.rel = 'stylesheet' : darkmodeCss.rel = 'alternate stylesheet' }) } </script>
我建议你将它添加到
<head>
里的原因是这样可以让主题切换迅速,做到访问页面就可以直接显示夜间主题 ,而不会因为 css 渲染顺序的问题导致出现多余的颜色的画面。这部分就可以实现按时间和浏览器行为自动切换夜间主题,并且会查询 cookie 中的 theme,通过值来自动切换。
-
引入或者添加 darkmode.js,内容为
// Darkmode Copyright 2021 YexuanXiao under MIT license // darkmode method function changeTheme() { const darkmodeCss = document.getElementById('darkmode-css'); if (sessionStorage.getItem('darktheme') !== 'true') { darkmodeCss.rel = 'stylesheet' sessionStorage.setItem('darktheme', 'true') } else { darkmodeCss.rel = 'alternate stylesheet' sessionStorage.setItem('darktheme', 'false') } } // initlize darkmode button { const container = document.createElement('div'); const btn = document.createElement('input'); document.body.appendChild(container) container.appendChild(btn) btn.addEventListener('click', changeTheme) btn.type = 'button' btn.value = '🌓' btn.style.cssText = 'background-color: transparent !important; border: none; font-size: 25px; z-index: 999; position: fixed; right: 10%; bottom: 10%' }
第一部分是更换主题的方法,第二部分是动态创建切换主题的按钮。