复选框起作用,但没有动画

Posted

技术标签:

【中文标题】复选框起作用,但没有动画【英文标题】:Checkbox functioning, but not animating 【发布时间】:2021-12-05 14:40:39 【问题描述】:

我在我的网站的标题导航和移动菜单中使用暗模式切换。 两者都按应有的方式运行,但只有 1 会在单击时为开关设置动画。我还希望切换按钮旁边的文本在单击时从“暗”切换到“亮”。任何帮助将不胜感激。

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>

【问题讨论】:

这个应该会给你答案***.com/questions/68868558/… 【参考方案1】:

你的js和html有错误。

    在标签&lt;label class="theme-switch-mobile" for="checkbox2" &lt;input type="checkbox" id="checkbox2"/&gt; &lt;/label&gt; 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"]'); querySelectorAll 而不是 querySelector 然后 toggleSwitch.forEach(e =&gt; 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>

【讨论】:

localStorage 操作无法在 SO sn-ps 上运行 问题不在localStorage中 你的错误信息还有什么? "message": "SecurityError: The operation is insecure.",【参考方案2】:

您可以使用 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

访问 codepen 导致 localStorage 操作无法在 SO sn-ps 上运行 –

【讨论】:

以上是关于复选框起作用,但没有动画的主要内容,如果未能解决你的问题,请参考以下文章

复选框链接 - 显示内联和浮动左边不起作用

复选框设置为选中 = false 不起作用

SVG动画在Edge或IE中不起作用

Blazor 复选框绑定不起作用 - 服务器端

复选框验证不起作用

iCheck 复选框在颤动的 Android 网络视图中不起作用