admin管理员组文章数量:1201790
I am trying to add this dark mode feature in my app. It uses localstorage to store the user's preference for future usage. So the problem now is when the dark mode is enabled, and the page is reloaded for some reason, eg. if the user deliberately reloads the page, or submits a form, then there's a flicker of white background all over the page before it turns to be dark. It stays a fraction of a second. It just doesn't look professional.
Haven't found any solution yet. So please help me out.
PS. The snippet below won't work here in SO as the code includes localStorage
object.
Here's the code:
const toggleSwitch = document.querySelector('#dark-mode-button input[type="checkbox"]');
const currentTheme = localStorage.getItem('theme');
if (currentTheme) {
document.documentElement.setAttribute('data-theme', currentTheme);
if (currentTheme === 'dark') {
toggleSwitch.checked = true;
}
}
function switchTheme(e) {
if (e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
}else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light');
}
}
toggleSwitch.addEventListener('change', switchTheme, false);
:root {
--primary-color: #495057;
--bg-color-primary: #F5F5F5;
}
body{
background-color: var(--bg-color-primary);
}
[data-theme="dark"] {
--primary-color: #8899A6;
--bg-color-primary: #15202B;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
background-color: #fff;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
<div id="dark-mode-button">
<input id="chck" type="checkbox">Dark Mode
<label for="chck" class="check-trail">
<span class="check-handler"></span>
</label>
</div>
<table class="table">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
</tbody>
</table>
I am trying to add this dark mode feature in my app. It uses localstorage to store the user's preference for future usage. So the problem now is when the dark mode is enabled, and the page is reloaded for some reason, eg. if the user deliberately reloads the page, or submits a form, then there's a flicker of white background all over the page before it turns to be dark. It stays a fraction of a second. It just doesn't look professional.
Haven't found any solution yet. So please help me out.
PS. The snippet below won't work here in SO as the code includes localStorage
object.
Here's the code:
const toggleSwitch = document.querySelector('#dark-mode-button input[type="checkbox"]');
const currentTheme = localStorage.getItem('theme');
if (currentTheme) {
document.documentElement.setAttribute('data-theme', currentTheme);
if (currentTheme === 'dark') {
toggleSwitch.checked = true;
}
}
function switchTheme(e) {
if (e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
}else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light');
}
}
toggleSwitch.addEventListener('change', switchTheme, false);
:root {
--primary-color: #495057;
--bg-color-primary: #F5F5F5;
}
body{
background-color: var(--bg-color-primary);
}
[data-theme="dark"] {
--primary-color: #8899A6;
--bg-color-primary: #15202B;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
background-color: #fff;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
<div id="dark-mode-button">
<input id="chck" type="checkbox">Dark Mode
<label for="chck" class="check-trail">
<span class="check-handler"></span>
</label>
</div>
<table class="table">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
</tbody>
</table>
Share
Improve this question
edited Apr 9, 2022 at 8:31
Anurag Srivastava
14.4k4 gold badges36 silver badges45 bronze badges
asked Jul 22, 2020 at 11:44
ZakZak
9404 gold badges20 silver badges44 bronze badges
8
|
Show 3 more comments
1 Answer
Reset to default 23It would be ideal to block the page rendering by placing a small <script>
tag inside the <head>
of your Document. By doing so the DOM parser should stop and call the JavaScript interpreter, assign the data-theme
attribute to <html>
and then continue where left.
Place this <script>
inside <head>
- even before the <link>
or <style>
tags:
<head>
<script>
// IMPORTANT: set this in <HEAD> top before any other tag.
const setTheme = (theme) => {
theme ??= localStorage.theme || "light";
document.documentElement.dataset.theme = theme;
localStorage.theme = theme;
};
setTheme();
</script>
<!-- meta, title, etc... -->
<!-- link, style, etc... -->
</head>
Then, right before the closing </body>
tag use all the other scripts in a non-render-blocking manner:
<script src="js/index.js"></script>
<!-- other <script> tags here -->
<!-- Closing </body> </html> goes here -->
and inside your i.e: js/index.js
file use:
const elToggleTheme = document.querySelector('#dark-mode-button input[type="checkbox"]');
elToggleTheme.checked = localStorage.theme === "dark";
elToggleTheme.addEventListener("change", () => {
const theme = elToggleTheme.checked ? "dark" : "light";
setTheme(theme);
});
PS: You can also place the above JavaScript code into your .js file if you want to keep all your scripts in one place.
If you need a creative idea for a Dark theme mode toggle checkbox see this answer: Toggle theme button
本文标签: javascriptDark mode flickers a white background for a millisecond on reloadStack Overflow
版权声明:本文标题:javascript - Dark mode flickers a white background for a millisecond on reload - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738599162a2101962.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
<head>
of your document. Place the remaining scripts as usual, right before the closing</body>
tag. That way, the browser will stop to interpret your JS inside head and will assign the neededdata-theme
attribute to your<html>
tag. – Roko C. Buljan Commented Jul 22, 2020 at 11:59querySelector
you may need event delegation if you are to prioritize the loading of this script – 95faf8e76605e973 Commented Jul 22, 2020 at 12:06