[英]How do I fix the blink of an light theme?
I have a dark/light switch.我有一个暗/光开关。 I keep users dark/light preference with cookies.
我用 cookie 保持用户的暗/亮偏好。 So when they visit again, they will see their preferred theme.
所以当他们再次访问时,他们会看到他们喜欢的主题。 But there is an annoying problem.
但是有一个恼人的问题。 Each time I refresh the page, the page reveals the light theme for a short time and then takes on the dark theme again.
每次刷新页面时,页面都会短暂显示浅色主题,然后再次呈现深色主题。 How to fix this?
如何解决这个问题?
const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); function switchTheme(e) { if (e.target.checked) { document.documentElement.setAttribute('data-theme', 'dark'); localStorage.setItem('theme', 'dark'); //add this } else { document.documentElement.setAttribute('data-theme', 'light'); localStorage.setItem('theme', 'light'); //add this } } toggleSwitch.addEventListener('change', switchTheme, false); const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; if (currentTheme) { document.documentElement.setAttribute('data-theme', currentTheme); if (currentTheme === 'dark') { toggleSwitch.checked = true; } }
:root { --bg-color: #fff; --panel-bg: #fff; --panel-bg-hover: #dcd8d8; --panel-border: #22a7f0; --panel-title-color: #22a7f0; --panel-title-hover: #0072b1; --panel-subtitle-color: #ffa500; --panel-text-color: #000000; --panel-button-bg: #dc4a4a; --panel-button-hover-bg: #d83535; --panel-button-text-color: #ffd7f8; --panel-button-text-hover-color: #ffd7f8; --input-bg: #e6e6e6; --input-border-color: #ff0000; --input-label-color: #ff0000; --input-label-color-focus: #ff0000; --input-text-color: #000000; --search-input-bg: #fff; --table-shorting: #22a7f0; --table-text-color-1: #417d9e; --table-text-color-2: #ff0000; --table-text-color-3: #008000; --table-text-color-4: #b17b17; --table-text-color-5: rgb(87, 89, 146); --table-options-color: #22a7f0; --table-options-hover-color: #e6e6e6; --dropdown-line-hover: #ddd; --active-color: #87D37C; --passive-color: #E74C3C; } [data-theme="dark"] { --bg-color: #2f2f2f; --panel-bg: #1e262c; --panel-bg-hover: #2f3a42; --panel-border: #ffa500; --panel-title-color: #ffa500; --panel-title-hover: #ffffffc2; --panel-subtitle-color: #c3c6ce; --panel-text-color: #ffffff; --panel-button-bg: #dc4a4a; --panel-button-hover-bg: #d83535; --panel-button-text-color: #ffd7f8; --panel-button-text-hover-color: #ffd7f8; --input-bg: #1a2025; --input-border-color: #3694ff; --input-label-color: #cad1ff4d; --input-label-color-focus: #3694ff; --input-text-color: white; --search-input-bg: #1e262c; --table-shorting: #ffa500; --table-text-color-1: #417d9e; --table-text-color-2: #ff6262; --table-text-color-3: #358e65; --table-text-color-4: #3eafa4; --table-text-color-5: #40c57b; --table-options-color: #ffa500; --table-options-hover-color: #ffa50042; --dropdown-line-hover: #634747; --active-color: #0f980f; --passive-color: #bf1e0e; } body { background-color: var(--bg-color); } .squares { display: inline-block; margin-top: 30px;} .square1 {display: inline-block; width: 100px; height: 100px; background-color: var(--table-text-color-1); margin-right: 20px;} .square2 {display: inline-block; width: 100px; height: 100px; background-color: var(--table-text-color-2); margin-right: 20px;} .square3 {display: inline-block; width: 100px; height: 100px; background-color: var(--table-text-color-3); margin-right: 20px;} .square4 {display: inline-block; width: 100px; height: 100px; background-color: var(--table-text-color-4); margin-right: 20px;} .theme-switch-wrapper { display: flex; align-items: center; position: -webkit-sticky; position: sticky; top: 10px; } .theme-switch { display: inline-block; height: 26px; position: relative; width: 52px; } .theme-switch input { display:none; } .slider { background-color: #ccc0; border: 3px solid #a5a4a4; bottom: 0; cursor: pointer; left: 0; position: absolute; right: 0; top: 0; transition: .4s; } .slider:before { content: ""; position: absolute; width: 16px; height: 16px; background-color: #a5a4a4; bottom: 1.8px; left: 3px; transform: rotate(-45deg); transition: .4s; border-radius: 100%; } #darklightswitch:checked + .slider { border: 3px solid #3694ff; } #darklightswitch:checked + .slider:before { box-shadow: 5px 5px 0 0 #3694ff; background: 0 0; left: 21.1px; } .slider.round { border-radius: 34px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <body> <div class="theme-switch-wrapper"> <label class="theme-switch" for="darklightswitch"> <input type="checkbox" id="darklightswitch" /> <div class="slider round"></div> </label> </div> <div class="squares"> <div class="square1"></div> <div class="square2"></div> <div class="square3"></div> <div class="square4"></div> </div> </body>
My source: https://dev.to/ananyaneogi/create-a-dark-light-mode-switch-with-css-variables-34l8我的来源: https : //dev.to/ananyaneogi/create-a-dark-light-mode-switch-with-css-variables-34l8
Pen: https://codepen.io/lastofdead/pen/dyPdPWY笔: https : //codepen.io/lastofdead/pen/dyPdPWY
Edit:编辑:
My real index page;我的真实索引页;
<html>
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex, nofollow">
<!-- JS -->
<script src="js/sweetalert2.all.js"></script>
<script src="js/jquery-3.3.1.min.js" type="text/javascript"></script>
<script src="js/jquery.maskedinput.js?ver=1" type="text/javascript"></script>
<!-- CSS -->
<link href="css/darklight.css?ver=2.01" rel="stylesheet" type="text/css" />
<link href="css/style.css?ver=2.02" rel="stylesheet" type="text/css" />
<link href="css/print.css?ver=2.00" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="theme-switch-wrapper">
<label class="theme-switch" for="darklightswitch">
<input type="checkbox" id="darklightswitch" />
<div class="slider round"></div>
</label>
</div>
<!-- some divs -->
<script src="js/darklightswitch.js?ver=2.04" type="text/javascript"></script>
<script src="js/dropdown-responsive.js?ver=2.00"></script>
<script src='js/jquery.dataTables.min.js?ver=2.00' type="text/javascript"></script>
<script src="js/input.js" type="text/javascript"></script>
<script src="js/sweet-js.js?ver=2.00"></script>
</body>
</html>
EDIT 2编辑 2
This is the last.这是最后一次了。 I'm still having the same problem.
我仍然有同样的问题。
<html>
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex, nofollow">
<!-- JS -->
<script src="js/sweetalert2.all.js"></script>
<script src="js/jquery-3.3.1.min.js" type="text/javascript"></script>
<script src="js/jquery.maskedinput.js?ver=1" type="text/javascript"></script>
<script type="text/javascript">
const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
function switchTheme(e) {
if (e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark'); //add this
}
else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light'); //add this
}
}
toggleSwitch.addEventListener('change', switchTheme, false);
/* çerezleme */
const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
if (currentTheme) {
document.documentElement.setAttribute('data-theme', currentTheme);
if (currentTheme === 'dark') {
toggleSwitch.checked = true;
}
}
</script>
<!-- CSS -->
<style>
:root {
--bg-color: #2f2f2f;
--panel-bg: #fff;
--panel-bg-hover: #dcd8d8;
--panel-border: #22a7f0;
--panel-title-color: #22a7f0;
--panel-title-hover: #0072b1;
--panel-subtitle-color: #ffa500;
--panel-text-color: #000000;
--panel-button-bg: #dc4a4a;
--panel-button-hover-bg: #d83535;
--panel-button-text-color: #ffd7f8;
--panel-button-text-hover-color: #ffd7f8;
--input-bg: #e6e6e6;
--input-border-color: #ff0000;
--input-label-color: #ff0000;
--input-label-color-focus: #ff0000;
--input-text-color: #000000;
--search-input-bg: #fff;
--table-shorting: #22a7f0;
--table-text-color-1: #417d9e;
--table-text-color-2: #ff0000;
--table-text-color-3: #008000;
--table-text-color-4: #b17b17;
--table-text-color-5: rgb(87, 89, 146);
--table-options-color: #22a7f0;
--table-options-hover-color: #e6e6e6;
--dropdown-line-hover: #ddd;
--active-color: #87D37C;
--passive-color: #E74C3C;
}
[data-theme="dark"] {
--bg-color: #2f2f2f;
--panel-bg: #1e262c;
--panel-bg-hover: #2f3a42;
--panel-border: #ffa500;
--panel-title-color: #ffa500;
--panel-title-hover: #ffffffc2;
--panel-subtitle-color: #c3c6ce;
--panel-text-color: #ffffff;
--panel-button-bg: #dc4a4a;
--panel-button-hover-bg: #d83535;
--panel-button-text-color: #ffd7f8;
--panel-button-text-hover-color: #ffd7f8;
--input-bg: #1a2025;
--input-border-color: #3694ff;
--input-label-color: #cad1ff4d;
--input-label-color-focus: #3694ff;
--input-text-color: white;
--search-input-bg: #1e262c;
--table-shorting: #ffa500;
--table-text-color-1: #417d9e;
--table-text-color-2: #ff6262;
--table-text-color-3: #358e65;
--table-text-color-4: #3eafa4;
--table-text-color-5: #40c57b;
--table-options-color: #ffa500;
--table-options-hover-color: #ffa50042;
--dropdown-line-hover: #634747;
--active-color: #0f980f;
--passive-color: #bf1e0e;
}
</style>
<link href="css/style.css?ver=2.02" rel="stylesheet" type="text/css" />
<link href="css/print.css?ver=2.00" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="theme-switch-wrapper">
<label class="theme-switch" for="darklightswitch">
<input type="checkbox" id="darklightswitch" />
<div class="slider round"></div>
</label>
</div>
<!-- some divs -->
<script src="js/dropdown-responsive.js?ver=2.00"></script>
<script src='js/jquery.dataTables.min.js?ver=2.00' type="text/javascript"></script>
<script src="js/input.js" type="text/javascript"></script>
<script src="js/sweet-js.js?ver=2.00"></script>
</body>
</html>
This is not a typical solution but i guess it will do the trick and will reduce the load time as possible.这不是典型的解决方案,但我想它可以解决问题并尽可能减少加载时间。
Your structure should look like this:您的结构应如下所示:
<html>
<head>
<!-- -->
<style>/* INLINE CSS */</style>
<!-- OTHER CSS STYLESHEETS -->
</head>
<body>
<!-- CONTENT -->
<!-- INLINE JS -->
<!-- OTHER DEFERRED JS SCRIPTS -->
</body>
</html>
In your example :在你的例子中:
<head>
<!-- meta -->
<style>
/* Inline critical CSS */
/* Define style directly, no need for root */
[data-theme="light"] {
--bg-color: #fff;
--panel-bg: #fff;
--panel-bg-hover: #dcd8d8;
--panel-border: #22a7f0;
--panel-title-color: #22a7f0;
--panel-title-hover: #0072b1;
--panel-subtitle-color: #ffa500;
--panel-text-color: #000000;
--panel-button-bg: #dc4a4a;
--panel-button-hover-bg: #d83535;
--panel-button-text-color: #ffd7f8;
--panel-button-text-hover-color: #ffd7f8;
--input-bg: #e6e6e6;
--input-border-color: #ff0000;
--input-label-color: #ff0000;
--input-label-color-focus: #ff0000;
--input-text-color: #000000;
--search-input-bg: #fff;
--table-shorting: #22a7f0;
--table-text-color-1: #417d9e;
--table-text-color-2: #ff0000;
--table-text-color-3: #008000;
--table-text-color-4: #b17b17;
--table-text-color-5: rgb(87, 89, 146);
--table-options-color: #22a7f0;
--table-options-hover-color: #e6e6e6;
--dropdown-line-hover: #ddd;
--active-color: #87D37C;
--passive-color: #E74C3C;
}
[data-theme="dark"] {
--bg-color: #2f2f2f;
--panel-bg: #1e262c;
--panel-bg-hover: #2f3a42;
--panel-border: #ffa500;
--panel-title-color: #ffa500;
--panel-title-hover: #ffffffc2;
--panel-subtitle-color: #c3c6ce;
--panel-text-color: #ffffff;
--panel-button-bg: #dc4a4a;
--panel-button-hover-bg: #d83535;
--panel-button-text-color: #ffd7f8;
--panel-button-text-hover-color: #ffd7f8;
--input-bg: #1a2025;
--input-border-color: #3694ff;
--input-label-color: #cad1ff4d;
--input-label-color-focus: #3694ff;
--input-text-color: white;
--search-input-bg: #1e262c;
--table-shorting: #ffa500;
--table-text-color-1: #417d9e;
--table-text-color-2: #ff6262;
--table-text-color-3: #358e65;
--table-text-color-4: #3eafa4;
--table-text-color-5: #40c57b;
--table-options-color: #ffa500;
--table-options-hover-color: #ffa50042;
--dropdown-line-hover: #634747;
--active-color: #0f980f;
--passive-color: #bf1e0e;
}
body {
background-color: var(--bg-color);
}
.theme-switch-wrapper {
display: flex;
align-items: center;
position: -webkit-sticky;
position: sticky;
top: 10px;
}
.theme-switch {
display: inline-block;
height: 26px;
position: relative;
width: 52px;
}
.theme-switch input {
display: none;
}
.slider {
background-color: #ccc0;
border: 3px solid #a5a4a4;
bottom: 0;
cursor: pointer;
left: 0;
position: absolute;
right: 0;
top: 0;
transition: .4s;
}
.slider:before {
content: "";
position: absolute;
width: 16px;
height: 16px;
background-color: #a5a4a4;
bottom: 1.8px;
left: 3px;
transform: rotate(-45deg);
transition: .4s;
border-radius: 100%;
}
#darklightswitch:checked+.slider {
border: 3px solid #3694ff;
}
#darklightswitch:checked+.slider:before {
box-shadow: 5px 5px 0 0 #3694ff;
background: 0 0;
left: 21.1px;
}
.slider.round {
border-radius: 34px;
}
</style>
<!-- LINK OTHER CSS STYLESHEETS -->
</head>
<body>
<!-- CONTENT HERE -->
<script>
// Pure JS not need for jQuery
// getElementById will save you some Millisecond
const toggleSwitch = document.getElementById('darklightswitch');
// First thing first check for saved value
const currentTheme = localStorage.getItem("theme") || null;
if (currentTheme) {
document.body.setAttribute("data-theme", currentTheme);
if (currentTheme === "dark") toggleSwitch.checked = true
}
// If not for some reasons set a fallback
else {
document.body.setAttribute("data-theme", "light");
}
toggleSwitch.addEventListener("change", e => {
if (e.target.checked) {
document.body.setAttribute("data-theme", "dark");
localStorage.setItem("theme", "dark");
} else {
document.body.setAttribute("data-theme", "light");
localStorage.setItem("theme", "light");
}
});
</script>
<!-- OTHER JS SCRIPTS Add defer tag to all -->
<script src="js/jquery-3.3.1.min.js" type="text/javascript" defer></script>
<script src="js/sweetalert2.all.js" defer></script>
<script src="js/jquery.maskedinput.js?ver=1" type="text/javascript" defer></script>
</body>
I found the perfect solution for myself.我为自己找到了完美的解决方案。 @awran5 's solution worked well.
@awran5 的解决方案运行良好。 But it was like hell for slow internet and computers.
但对于缓慢的互联网和计算机来说,这就像地狱。 Because the site was opening piece by piece.
因为网站是一块一块地打开。 That didn't look very good either.
那看起来也不是很好。 I'm writing this for alternative seekers.
我正在为其他寻求者写这篇文章。
My solution is the database.我的解决方案是数据库。
First of all, I get the person's theme selection from the database.首先,我从数据库中获取该人的主题选择。
$getheme = mysql_query("SELECT theme FROM accounts WHERE id='$accountid'");
$pull = mysql_fetch_array($getheme);
$currentheme = $pull['theme'];
(I know, mysql_ very old. I'll replace it with mysqli_ as soon as possible. ) (我知道,mysql_很旧。我会尽快用mysqli_替换它。)
I add this to the body.我把这个加到身体上。
<body data-theme="<?php echo $currentheme ?>">
I gave input a name.我输入了一个名字。
<input type="checkbox" id="darklightswitch" name="darklightswitch" />
Switch needs to know which theme we're in. Switch 需要知道我们在哪个主题中。
const toggleSwitch = document.querySelector('input[name="darklightswitch"]');
const currentTheme = "<?php echo $currentheme; ?>";
if (currentTheme === 'dark') {
toggleSwitch.checked = true;
}
Finally, when we change Switch, the new theme value should go to the database.最后,当我们更改 Switch 时,新的主题值应该进入数据库。
$('input[name=darklightswitch]').click(function(){
var id = $(this).attr('id');
if($("#darklightswitch").prop('checked') == true) {
var theme = "dark";
} else if ($("#darklightswitch").prop('checked') == false) {
var theme = "light";
}
$.ajax({
type:'POST',
url:'themeswitch.php',
data: {aid: <?php echo $accountid; ?>, theme: theme},
success:function(result){
location.reload();
}
});
});
themeswitch.php主题切换.php
$account_id = htmlspecialchars($_POST["aid"]);
$theme = htmlspecialchars($_POST["theme"]);
mysql_query("UPDATE accounts SET theme = '$theme' WHERE id='$account_id'");
Final content;最终内容;
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex, nofollow">
<style type="text/css">
[data-theme="light"] {
--bg-color: #2f2f2f;
--panel-bg: #fff;
--panel-bg-hover: #dcd8d8;
--panel-border: #22a7f0;
--panel-title-color: #22a7f0;
--panel-title-hover: #0072b1;
--panel-subtitle-color: #ffa500;
--panel-subtitle-color-hover: #22a7f0;
--panel-text-color: #000000;
--panel-button-bg: #dc4a4a;
--panel-button-hover-bg: #d83535;
--panel-button-text-color: #ffd7f8;
--panel-button-text-hover-color: #ffd7f8;
--input-bg: #e6e6e6;
--input-border-color: #ff0000;
--input-label-color: #ff0000;
--input-label-color-focus: #ff0000;
--input-text-color: #000000;
--search-input-bg: #fff;
--table-shorting: #22a7f0;
--table-text-color-1: #417d9e;
--table-text-color-2: #ff0000;
--table-text-color-3: #008000;
--table-text-color-4: #b17b17;
--table-text-color-5: rgb(87, 89, 146);
--table-options-color: #22a7f0;
--table-options-hover-color: #e6e6e6;
--dropdown-line-hover: #ddd;
--active-color: #87D37C;
--passive-color: #E74C3C;
}
[data-theme="dark"] {
--bg-color: #2f2f2f;
--panel-bg: #1e262c;
--panel-bg-hover: #2f3a42;
--panel-border: #ffa500;
--panel-title-color: #ffa500;
--panel-title-hover: #ffffffc2;
--panel-subtitle-color: #c3c6ce;
--panel-subtitle-color-hover: #ffa500;
--panel-text-color: #ffffff;
--panel-button-bg: #dc4a4a;
--panel-button-hover-bg: #d83535;
--panel-button-text-color: #ffd7f8;
--panel-button-text-hover-color: #ffd7f8;
--input-bg: #1a2025;
--input-border-color: #3694ff;
--input-label-color: #cad1ff4d;
--input-label-color-focus: #3694ff;
--input-text-color: white;
--search-input-bg: #1e262c;
--table-shorting: #ffa500;
--table-text-color-1: #417d9e;
--table-text-color-2: #ff6262;
--table-text-color-3: #358e65;
--table-text-color-4: #3eafa4;
--table-text-color-5: #40c57b;
--table-options-color: #ffa500;
--table-options-hover-color: #ffa50042;
--dropdown-line-hover: #634747;
--active-color: #0f980f;
--passive-color: #bf1e0e;
}
</style>
<!-- FONT -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet prefetch">
<link href='https://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
<link rel='stylesheet' href='https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css'>
<!-- JS -->
<script src="js/jquery-3.3.1.min.js" type="text/javascript"></script>
<!-- CSS -->
<link href="css/style.css?ver=22" rel="stylesheet" type="text/css" />
</head>
<?php
$getheme = mysql_query("SELECT theme FROM accounts WHERE id='$accountid'");
$pull = mysql_fetch_array($getheme);
$currentheme = $pull['theme'];
?>
<body data-theme="<?php echo $currentheme ?>">
<div class="theme-switch-wrapper">
<label class="theme-switch" for="darklightswitch">
<input type="checkbox" id="darklightswitch" name="darklightswitch" />
<div class="slider round"></div>
</label>
</div>
<script type="text/javascript">
$('input[name=darklightswitch]').click(function(){
var id = $(this).attr('id');
if($("#darklightswitch").prop('checked') == true) {
var theme = "dark";
} else if ($("#darklightswitch").prop('checked') == false) {
var theme = "light";
}
$.ajax({
type:'POST',
url:'themeswitch.php',
data: {aid: <?php echo $accountid; ?>, theme: theme},
success:function(result){
location.reload();
}
});
});
</script>
// some content
<script type="text/javascript">
const toggleSwitch = document.querySelector('input[name="darklightswitch"]');
const currentTheme = "<?php echo $currentheme; ?>";
if (currentTheme === 'dark') {
toggleSwitch.checked = true;
}
</script>
<script src='js/jquery.dataTables.min.js?ver=2.00' type="text/javascript"></script>
</body>
</html>
What you have to do is call the javascript function right after opening of body tag.您需要做的是在打开 body 标签后立即调用 javascript 函数。 Then in the function get the theme type is it dark or light and add that class to body.
然后在函数中获取主题类型是深色还是浅色并将该类添加到正文中。
For this to work your css has to be structure like mine.为此,您的 css 必须具有像我这样的结构。
this way you dont need loadiang splash or backend to handle it这样你就不需要 loadiang splash 或后端来处理它
div, p{ width: 200px; height: 200px; color: red; } body.dark div, body.dark p{ background: black; } body.light div, body.light p{ background: grey; } body.dark .heading{ font-size: 6em; } body.light .heading{ font-size: 1.7em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> function changeTheme(){ var themeClassName = "dark"; // get it from cookie $("body").addClass(themeClassName); } </script> <body> <script>changeTheme()</script> <div> hello </div> <p class="heading"> world </p> </body>
您还可以添加在 js 加载时显示的加载启动画面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.