根据 localStorage 布尔值在 if 条件下处理 addEventListener
handle addEventListener in if condition based on localStorage boolean value
我正在尝试根据 OS 级别 light/dark 模式切换主题。用户在使用网站时可能会更改系统设置。所以,我需要实时更新而不是页面刷新。所以,我正在使用 addEventListener
来获取系统当前的变化。 addEventListener
工作正常。但是,如果系统设置选项设置为 true,它应该可以工作。
我已将系统设置作为布尔选项存储在 localStorage 中。 如果为真,则唯一的 addEventListener 应该起作用。如果它是假的,它应该不起作用。 但是,我的问题是 addEventListener 在这两种情况下都有效。我的意思是,如果系统设置既不是 true 也不是 false,它就可以工作。我如何处理 addEventListener 应该基于 localStorage 值工作(如果系统设置设置为真)?
JS
function defaultFunction() {
localStorage.setItem('option', 'default');
localStorage.setItem('systemOption', false);
}
defaultFunction();
function myFunction() {
let getOption = localStorage.getItem('option');
let themeDiv = document.getElementById('theme');
if(localStorage.getItem('systemOption') == 'true') {
let osTheme = window.matchMedia('(prefers-color-scheme: dark)');
osTheme.addEventListener('change', event => {
if(event.matches) {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
})
} else {
if(getOption == 'dark') {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else if(getOption == 'default') {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
}
}
myFunction();
function setDark() {
localStorage.setItem('option', 'dark');
myFunction();
}
function setLight() {
localStorage.setItem('option', 'default');
myFunction();
}
function checkBox() {
let cBox = document.getElementById('system');
let sun = document.getElementById('sun');
let moon = document.getElementById('moon');
if(cBox.checked) {
localStorage.setItem('systemOption', true);
sun.classList.add('addOpacity');
moon.classList.add('addOpacity');
} else {
localStorage.setItem('systemOption', false);
sun.classList.remove('addOpacity');
moon.classList.remove('addOpacity');
}
myFunction();
}
现在可以了。
<div id="theme">
Testing based on User OS level light/dark theme
</div>
<div class="option">
<span id="sun" class="lightCls" onclick="setLight();">Light</span>
<span id="moon" class="darkCls" onclick="setDark();">Dark</span>
<span>
<input type="checkbox" id="system" onclick="checkBox();" />
<label for="system">System Setttings</label>
</span>
</div>
<style>
* {
margin: 0;
padding: 0;
}
#theme {
width: 100%;
height: 100vh;
}
.default {
background: #ddd;
color: #000;
}
.dark {
background: #101010;
color: #fff;
}
.option {
position: absolute;
right: 0;
bottom: 0;
background: #fff;
border: 1px solid #ccc;
padding: 3px;
}
.lightCls, .darkCls {
padding: 2px;
cursor: pointer;
}
.lightCls {
background: #ddd;
color: #000;
}
.darkCls {
background: #101010;
color: #fff;
}
.addOpacity {
opacity: 0.2;
pointer-events: none;
}
</style>
<script>
function defaultFunction() {
localStorage.setItem('option', 'default');
localStorage.setItem('systemOption', false);
}
defaultFunction();
function myFunction() {
let getOption = localStorage.getItem('option');
let themeDiv = document.getElementById('theme');
if(localStorage.getItem('systemOption') == 'true') {
let osTheme = window.matchMedia('(prefers-color-scheme: dark)');
osTheme.addEventListener('change', event => {
if(event.matches) {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
})
} else {
if(getOption == 'dark') {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else if(getOption == 'default') {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
}
}
myFunction();
function setDark() {
localStorage.setItem('option', 'dark');
myFunction();
}
function setLight() {
localStorage.setItem('option', 'default');
myFunction();
}
function checkBox() {
let cBox = document.getElementById('system');
let sun = document.getElementById('sun');
let moon = document.getElementById('moon');
if(cBox.checked) {
localStorage.setItem('systemOption', true);
sun.classList.add('addOpacity');
moon.classList.add('addOpacity');
} else {
localStorage.setItem('systemOption', false);
sun.classList.remove('addOpacity');
moon.classList.remove('addOpacity');
}
myFunction();
}
</script>
我认为问题在于您正在添加一个事件侦听器,但您从未将其删除,因此它始终在侦听该事件。
有条件地尝试 adding/removing 事件侦听器,如下所示
function changeListener(event) {
if(event.matches) {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
}
let osTheme = window.matchMedia('(prefers-color-scheme: dark)');
if(localStorage.getItem('systemOption') === 'true') {
osTheme.addEventListener('change', changeListener);
} else {
osTheme.removeEventListener('change', changeListener);
}
或
始终监听事件并通过检查 localStorage
有条件地应用主题
const osTheme = window.matchMedia('(prefers-color-scheme: dark)');
osTheme.addEventListener('change', event => {
if(localStorage.getItem('systemOption') === 'true') {
if(event.matches) {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
}
});
我正在尝试根据 OS 级别 light/dark 模式切换主题。用户在使用网站时可能会更改系统设置。所以,我需要实时更新而不是页面刷新。所以,我正在使用 addEventListener
来获取系统当前的变化。 addEventListener
工作正常。但是,如果系统设置选项设置为 true,它应该可以工作。
我已将系统设置作为布尔选项存储在 localStorage 中。 如果为真,则唯一的 addEventListener 应该起作用。如果它是假的,它应该不起作用。 但是,我的问题是 addEventListener 在这两种情况下都有效。我的意思是,如果系统设置既不是 true 也不是 false,它就可以工作。我如何处理 addEventListener 应该基于 localStorage 值工作(如果系统设置设置为真)?
JS
function defaultFunction() {
localStorage.setItem('option', 'default');
localStorage.setItem('systemOption', false);
}
defaultFunction();
function myFunction() {
let getOption = localStorage.getItem('option');
let themeDiv = document.getElementById('theme');
if(localStorage.getItem('systemOption') == 'true') {
let osTheme = window.matchMedia('(prefers-color-scheme: dark)');
osTheme.addEventListener('change', event => {
if(event.matches) {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
})
} else {
if(getOption == 'dark') {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else if(getOption == 'default') {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
}
}
myFunction();
function setDark() {
localStorage.setItem('option', 'dark');
myFunction();
}
function setLight() {
localStorage.setItem('option', 'default');
myFunction();
}
function checkBox() {
let cBox = document.getElementById('system');
let sun = document.getElementById('sun');
let moon = document.getElementById('moon');
if(cBox.checked) {
localStorage.setItem('systemOption', true);
sun.classList.add('addOpacity');
moon.classList.add('addOpacity');
} else {
localStorage.setItem('systemOption', false);
sun.classList.remove('addOpacity');
moon.classList.remove('addOpacity');
}
myFunction();
}
现在可以了。
<div id="theme">
Testing based on User OS level light/dark theme
</div>
<div class="option">
<span id="sun" class="lightCls" onclick="setLight();">Light</span>
<span id="moon" class="darkCls" onclick="setDark();">Dark</span>
<span>
<input type="checkbox" id="system" onclick="checkBox();" />
<label for="system">System Setttings</label>
</span>
</div>
<style>
* {
margin: 0;
padding: 0;
}
#theme {
width: 100%;
height: 100vh;
}
.default {
background: #ddd;
color: #000;
}
.dark {
background: #101010;
color: #fff;
}
.option {
position: absolute;
right: 0;
bottom: 0;
background: #fff;
border: 1px solid #ccc;
padding: 3px;
}
.lightCls, .darkCls {
padding: 2px;
cursor: pointer;
}
.lightCls {
background: #ddd;
color: #000;
}
.darkCls {
background: #101010;
color: #fff;
}
.addOpacity {
opacity: 0.2;
pointer-events: none;
}
</style>
<script>
function defaultFunction() {
localStorage.setItem('option', 'default');
localStorage.setItem('systemOption', false);
}
defaultFunction();
function myFunction() {
let getOption = localStorage.getItem('option');
let themeDiv = document.getElementById('theme');
if(localStorage.getItem('systemOption') == 'true') {
let osTheme = window.matchMedia('(prefers-color-scheme: dark)');
osTheme.addEventListener('change', event => {
if(event.matches) {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
})
} else {
if(getOption == 'dark') {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else if(getOption == 'default') {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
}
}
myFunction();
function setDark() {
localStorage.setItem('option', 'dark');
myFunction();
}
function setLight() {
localStorage.setItem('option', 'default');
myFunction();
}
function checkBox() {
let cBox = document.getElementById('system');
let sun = document.getElementById('sun');
let moon = document.getElementById('moon');
if(cBox.checked) {
localStorage.setItem('systemOption', true);
sun.classList.add('addOpacity');
moon.classList.add('addOpacity');
} else {
localStorage.setItem('systemOption', false);
sun.classList.remove('addOpacity');
moon.classList.remove('addOpacity');
}
myFunction();
}
</script>
我认为问题在于您正在添加一个事件侦听器,但您从未将其删除,因此它始终在侦听该事件。
有条件地尝试 adding/removing 事件侦听器,如下所示
function changeListener(event) {
if(event.matches) {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
}
let osTheme = window.matchMedia('(prefers-color-scheme: dark)');
if(localStorage.getItem('systemOption') === 'true') {
osTheme.addEventListener('change', changeListener);
} else {
osTheme.removeEventListener('change', changeListener);
}
或
始终监听事件并通过检查 localStorage
const osTheme = window.matchMedia('(prefers-color-scheme: dark)');
osTheme.addEventListener('change', event => {
if(localStorage.getItem('systemOption') === 'true') {
if(event.matches) {
themeDiv.classList.add("dark");
themeDiv.classList.remove("default");
} else {
themeDiv.classList.add("default");
themeDiv.classList.remove("dark");
}
}
});