复选框功能正常,但没有动画

Checkbox functioning, but not animating

我在我网站的 header 导航和移动菜单中使用暗模式切换。 两者都按应有的方式运行,除了只有 1 在单击时为切换 on/off 设置动画。我还希望切换按钮旁边的文本在单击时从“深色”切换到“浅色”。任何帮助将不胜感激。

const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"], .theme-switch-mobile input[type="checkbox2"]');

function switchTheme(e) {
    if (e.target.checked) {
        document.documentElement.setAttribute('data-theme', 'dark');
    }
    else {
        document.documentElement.setAttribute('data-theme', 'light');
    }    
}

toggleSwitch.addEventListener('change', switchTheme, false);

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
    }    
}

const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;

if (currentTheme) {
    document.documentElement.setAttribute('data-theme', currentTheme);

    if (currentTheme === 'dark') {
        toggleSwitch.checked = true;
    }
}
/********** DARK THEME TOGGLE START **********/
    
.theme-switch-wrapper {
  display: flex;
  align-items: center;
}
    
.theme-switch-wrapper p {
  font-family: Arial MT Pro!important;
  margin-top: 10px;
  margin-left: 5px;
  font-size: 9px;
  letter-spacing: 2px;
}
    
[data-theme="dark"] .theme-switch-wrapper p {
  font-family: Arial MT Pro!important;
  margin-top: 10px;
  margin-left: 5px;
  font-size: 9px;
  letter-spacing: 2px;
  color: #F8F0E3;
}
    
.theme-switch {
  display: inline-block;
  height: 18px;
  position: relative;
  width: 30px;
  margin-top: -4px;
}

.theme-switch input {
  display:none;
}

.slider {
  background-color: #fff;
  bottom: 0;
  cursor: pointer;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  border: 2px solid #121212;
  transition: .4s;
  -webkit-transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -o-transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

.slider:before {
  background-color: #000;
  bottom: 1px;
  content: "";
  height: 12px;
  left: 2px;
  position: absolute;
  transition: .4s;
  width: 12px;
  -webkit-transform: translateX(0);
  -ms-transform: translateX(0);
  transform: translateX(0);
  transition: -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -webkit-transition: -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -o-transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1), -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

input:checked + .slider {
  background-color: transparent;
  border: 2px solid #F8F0E3;
}
input:checked + .slider:before {
  -webkit-transform: translateX(10px);
  -ms-transform: translateX(10px);
  transform: translateX(10px);
  background-color: #F8F0E3;
}

.slider.round {
  border-radius: 34px;
  border: 2px solid #000;
}

.slider.round:before {
  border-radius: 50%;
}
    
.header__toggle {
  position: absolute;
  top: 7px;
  right: 20px;
}
    
@media screen and (max-width: 768px) {    
.header__toggle {
  position: absolute;
  top: 0px;
  right: 10px;
}
}
    
.is-light .site-toggle__link{
   color:#fff!important;
}

[data-theme="dark"] .is-light .site-toggle__link{
   color:#F8F0E3!important;
}
  
[data-theme="dark"] .site-toggle__link{
  color: #000!important;
  color:var(--colorNavText)
}
   
/********** DARK THEME TOGGLE END **********/
    
/********** DARK THEME MOBILE TOGGLE START **********/
    
.theme-switch-mobile-wrapper {
  display: flex;
  align-items: center;
}
    
.theme-switch-mobile-wrapper p {
  font-family: Arial MT Pro!important;
  margin-top: 13px;
  margin-left: 7px;
  font-size: 24px;
  color: #ffffff;
  letter-spacing: 3px;
}
    
[data-theme=dark] .theme-switch-mobile-wrapper p {
    font-family: Arial MT Pro!important;
    margin-top: 13px;
    margin-left: 7px;
    font-size: 24px;
    color: #f8f0e3;
    letter-spacing: 3px;
}
    
.theme-switch-mobile {
    display: inline-block;
    height: 21px;
    position: relative;
    width: 33px;
    margin-top: -4px;
}

.theme-switch-mobile input {
  display:none;
}

.slider-mobile {
  background-color: #fff;
  bottom: 0;
  cursor: pointer;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  border: 2px solid #121212;
  transition: .4s;
  -webkit-transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -o-transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

.slider-mobile:before {
    background-color: #000;
    bottom: 1px;
    content: "";
    height: 15px;
    left: 2px;
    position: absolute;
    transition: .4s;
    width: 15px;
  -webkit-transform: translateX(0);
  -ms-transform: translateX(0);
  transform: translateX(0);
  transition: -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -webkit-transition: -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -o-transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1), -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

input:checked + .slider-mobile {
  background-color: transparent;
  border: 2px solid #F8F0E3;
}

input:checked + .slider-mobile:before {
  -webkit-transform: translateX(10px);
  -ms-transform: translateX(10px);
  transform: translateX(10px);
  background-color: #F8F0E3;
}

.slider-mobile.round-mobile {
  border-radius: 34px;
  border: 2px solid #000;
}

.slider-mobile.round-mobile:before {
  border-radius: 50%;
}

.mobile__toggle {
  position: absolute;
  left: 35%;
  margin-top: -15px;
}
    
@media screen and (max-width: 768px) {    
.mobile__toggle {
  position: absolute;
  left: 35%;
  margin-top: -15px;
}
}
   
/********** DARK THEME MOBILE TOGGLE END **********/
<div class="theme-switch-wrapper header__toggle site-toggle__link">
    <label class="theme-switch" for="checkbox">
        <input type="checkbox" id="checkbox" />
        <div class="slider round"></div>
    </label>
        <p>DARK</p>
</div>
    
<div class="theme-switch-mobile-wrapper mobile__toggle">
     <label class="theme-switch-mobile" for="checkbox">
        <input type="checkbox" id="checkbox2" />
        <div class="slider-mobile round-mobile"></div>
     </label>
        <p>DARK</p>
</div>

你的js和html有错误。

  1. 在标签中 <label class="theme-switch-mobile" for="checkbox2" <input type="checkbox" id="checkbox2"/> </label>
  2. const toggleSwitch = document.querySelectorAll('.theme-switch input, .theme-switch-mobile input'); 而不是 const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"], .theme-switch-mobile input[type="checkbox2"]');
  3. querySelectorAll 而不是 querySelector 然后 toggleSwitch.forEach(e => { e.addEventListener('change', switchTheme, false) } );

const toggleSwitch = document.querySelectorAll('.theme-switch input, .theme-switch-mobile input');

    function switchTheme(e) {
        if (e.target.checked) {
            document.documentElement.setAttribute('data-theme', 'dark');
        }
        else {
            document.documentElement.setAttribute('data-theme', 'light');
        }
    }

    toggleSwitch.forEach(e => {
            e.addEventListener('change', switchTheme, false)
        }
    );

    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
        }
    }

    //const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
 const currentTheme = null;

    if (currentTheme) {
        document.documentElement.setAttribute('data-theme', currentTheme);

        if (currentTheme === 'dark') {
            toggleSwitch.checked = true;
        }
    }
/********** DARK THEME TOGGLE START **********/
    
.theme-switch-wrapper {
  display: flex;
  align-items: center;
}
    
.theme-switch-wrapper p {
  font-family: Arial MT Pro!important;
  margin-top: 10px;
  margin-left: 5px;
  font-size: 9px;
  letter-spacing: 2px;
}
    
[data-theme="dark"] .theme-switch-wrapper p {
  font-family: Arial MT Pro!important;
  margin-top: 10px;
  margin-left: 5px;
  font-size: 9px;
  letter-spacing: 2px;
  color: #F8F0E3;
}
    
.theme-switch {
  display: inline-block;
  height: 18px;
  position: relative;
  width: 30px;
  margin-top: -4px;
}

.theme-switch input {
  display:none;
}

.slider {
  background-color: #fff;
  bottom: 0;
  cursor: pointer;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  border: 2px solid #121212;
  transition: .4s;
  -webkit-transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -o-transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

.slider:before {
  background-color: #000;
  bottom: 1px;
  content: "";
  height: 12px;
  left: 2px;
  position: absolute;
  transition: .4s;
  width: 12px;
  -webkit-transform: translateX(0);
  -ms-transform: translateX(0);
  transform: translateX(0);
  transition: -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -webkit-transition: -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -o-transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1), -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

input:checked + .slider {
  background-color: transparent;
  border: 2px solid #F8F0E3;
}
input:checked + .slider:before {
  -webkit-transform: translateX(10px);
  -ms-transform: translateX(10px);
  transform: translateX(10px);
  background-color: #F8F0E3;
}

.slider.round {
  border-radius: 34px;
  border: 2px solid #000;
}

.slider.round:before {
  border-radius: 50%;
}
    
.header__toggle {
  position: absolute;
  top: 7px;
  right: 20px;
}
    
@media screen and (max-width: 768px) {    
.header__toggle {
  position: absolute;
  top: 0px;
  right: 10px;
}
}
    
.is-light .site-toggle__link{
   color:#fff!important;
}

[data-theme="dark"] .is-light .site-toggle__link{
   color:#F8F0E3!important;
}
  
[data-theme="dark"] .site-toggle__link{
  color: #000!important;
  color:var(--colorNavText)
}
   
/********** DARK THEME TOGGLE END **********/
    
/********** DARK THEME MOBILE TOGGLE START **********/
    
.theme-switch-mobile-wrapper {
  display: flex;
  align-items: center;
}
    
.theme-switch-mobile-wrapper p {
  font-family: Arial MT Pro!important;
  margin-top: 13px;
  margin-left: 7px;
  font-size: 24px;
  color: #ffffff;
  letter-spacing: 3px;
}
    
[data-theme=dark] .theme-switch-mobile-wrapper p {
    font-family: Arial MT Pro!important;
    margin-top: 13px;
    margin-left: 7px;
    font-size: 24px;
    color: #f8f0e3;
    letter-spacing: 3px;
}
    
.theme-switch-mobile {
    display: inline-block;
    height: 21px;
    position: relative;
    width: 33px;
    margin-top: -4px;
}

.theme-switch-mobile input {
  display:none;
}

.slider-mobile {
  background-color: #fff;
  bottom: 0;
  cursor: pointer;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  border: 2px solid #121212;
  transition: .4s;
  -webkit-transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -o-transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: background-color 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

.slider-mobile:before {
    background-color: #000;
    bottom: 1px;
    content: "";
    height: 15px;
    left: 2px;
    position: absolute;
    transition: .4s;
    width: 15px;
  -webkit-transform: translateX(0);
  -ms-transform: translateX(0);
  transform: translateX(0);
  transition: -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -webkit-transition: -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  -o-transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
  transition: transform 0.4s cubic-bezier(0.23, 1, 0.32, 1), -webkit-transform 0.4s cubic-bezier(0.23, 1, 0.32, 1);
}

input:checked + .slider-mobile {
  background-color: transparent;
  border: 2px solid #F8F0E3;
}

input:checked + .slider-mobile:before {
  -webkit-transform: translateX(10px);
  -ms-transform: translateX(10px);
  transform: translateX(10px);
  background-color: #F8F0E3;
}

.slider-mobile.round-mobile {
  border-radius: 34px;
  border: 2px solid #000;
}

.slider-mobile.round-mobile:before {
  border-radius: 50%;
}

.mobile__toggle {
  position: absolute;
  left: 35%;
  margin-top: -15px;
}
    
@media screen and (max-width: 768px) {    
.mobile__toggle {
  position: absolute;
  left: 35%;
  margin-top: -15px;
}
}
   
/********** DARK THEME MOBILE TOGGLE END **********/
<div class="theme-switch-wrapper header__toggle site-toggle__link">
    <label class="theme-switch" for="checkbox">
        <input type="checkbox" id="checkbox" />
        <div class="slider round"></div>
    </label>
        <p>DARK</p>
</div>
    
<div class="theme-switch-mobile-wrapper mobile__toggle">
     <label class="theme-switch-mobile" for="checkbox2">
        <input type="checkbox" id="checkbox2" />
        <div class="slider-mobile round-mobile"></div>
     </label>
        <p>DARK</p>
</div>

你可以使用 Vataliy 的答案,但这只是改变一个切换的动画。我的回答改变了两个切换动画,但没有太大区别。

const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"], .theme-switch-mobile input[type="checkbox2"]');

const toggles = document.querySelectorAll('#checkbox2, #checkbox');

toggleSwitch.addEventListener('change', switchTheme, false);

function switchTheme(e) {
  console.log(toggles);
    if (e.target.checked) {
        document.documentElement.setAttribute('data-theme', 'dark');
        localStorage.setItem('theme', 'dark'); //add this
       toggles.forEach((toggle) => {
        toggle.checked = true;
  });
    }
    else {
        document.documentElement.setAttribute('data-theme', 'light');
        localStorage.setItem('theme', 'light'); //add this
     toggles.forEach((toggle) => {
        toggle.checked = false;
  });
    }   
}

const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;

if (currentTheme) {
    document.documentElement.setAttribute('data-theme', currentTheme);

    if (currentTheme === 'dark') {
        toggleSwitch.checked = true;
    }
}

https://codepen.io/naxsi-the-bashful/pen/NWvNMQv?editors=1111

access codepen 导致 localStorage 操作不能在 SO 片段上 运行 –