[英]How do I force Update my components in my react code to toggle dark theme to light theme
[英]How do I fix the blink of an light theme?
我有一个暗/光开关。 我用 cookie 保持用户的暗/亮偏好。 所以当他们再次访问时,他们会看到他们喜欢的主题。 但是有一个恼人的问题。 每次刷新页面时,页面都会短暂显示浅色主题,然后再次呈现深色主题。 如何解决这个问题?
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>
我的来源: https : //dev.to/ananyaneogi/create-a-dark-light-mode-switch-with-css-variables-34l8
笔: https : //codepen.io/lastofdead/pen/dyPdPWY
编辑:
我的真实索引页;
<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>
编辑 2
这是最后一次了。 我仍然有同样的问题。
<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>
这不是典型的解决方案,但我想它可以解决问题并尽可能减少加载时间。
您的结构应如下所示:
<html>
<head>
<!-- -->
<style>/* INLINE CSS */</style>
<!-- OTHER CSS STYLESHEETS -->
</head>
<body>
<!-- CONTENT -->
<!-- INLINE JS -->
<!-- OTHER DEFERRED JS SCRIPTS -->
</body>
</html>
在你的例子中:
<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>
您可以在此处测试实时示例
我为自己找到了完美的解决方案。 @awran5 的解决方案运行良好。 但对于缓慢的互联网和计算机来说,这就像地狱。 因为网站是一块一块地打开。 那看起来也不是很好。 我正在为其他寻求者写这篇文章。
我的解决方案是数据库。
首先,我从数据库中获取该人的主题选择。
$getheme = mysql_query("SELECT theme FROM accounts WHERE id='$accountid'");
$pull = mysql_fetch_array($getheme);
$currentheme = $pull['theme'];
(我知道,mysql_很旧。我会尽快用mysqli_替换它。)
我把这个加到身体上。
<body data-theme="<?php echo $currentheme ?>">
我输入了一个名字。
<input type="checkbox" id="darklightswitch" name="darklightswitch" />
Switch 需要知道我们在哪个主题中。
const toggleSwitch = document.querySelector('input[name="darklightswitch"]');
const currentTheme = "<?php echo $currentheme; ?>";
if (currentTheme === 'dark') {
toggleSwitch.checked = true;
}
最后,当我们更改 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();
}
});
});
主题切换.php
$account_id = htmlspecialchars($_POST["aid"]);
$theme = htmlspecialchars($_POST["theme"]);
mysql_query("UPDATE accounts SET theme = '$theme' WHERE id='$account_id'");
最终内容;
<!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>
您需要做的是在打开 body 标签后立即调用 javascript 函数。 然后在函数中获取主题类型是深色还是浅色并将该类添加到正文中。
为此,您的 css 必须具有像我这样的结构。
这样你就不需要 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.