[英]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.