【问题标题】:Body CSS not updating with .setProperty()正文 CSS 未使用 .setProperty() 更新
【发布时间】:2021-05-20 10:10:07
【问题描述】:

我正在尝试在网站上启用暗模式/亮模式功能,其中我使用 .setProperty 函数来更改变量的 HEX 值。但是,每当我切换开关时,该站点都不会更新。为什么是这样?以下是与问题有关的所有代码:

let color = "#141414";

function changeMode() {
  
  console.log("Switch was toggled. Switching site color scheme...")
  
  let bg = document.querySelector(':root');
  
  // Should switch the value of 'color' from grey to white, and vice versa
  if (color === "#141414") { color = "#ffffff"; } else if (color === "#ffffff") {  color = "#141414"; }
  
  bg.style.setProperty("--main2", color);

}
:root {

  --main1: #ffdb15;
  --main2: #141414;

}

html, body {

  background-color: var(--main2);
  
}

.switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
  left: 20px;
  top: 20px;

}

.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

input:checked + .slider {
  background-color: #5d00e2;
}

input:focus + .slider {
  box-shadow: 0 0 1px #5d00e2;
}

input:checked + .slider:before {
  -webkit-transform: translateX(26px);
  -ms-transform: translateX(26px);
  transform: translateX(26px);
}

.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
}
<label class = "switch" onclick = "changeMode()">
  <input type = "checkbox" checked>
  <span class = "slider round"> </span>
</label>

color变量的问题,还是在切换值时程序没有更新页面本身的问题?

编辑:另外,如果您知道任何改进我的代码的方法,请告诉我如何。具体来说,有什么方法可以改进切换颜色变量值的方法吗?

【问题讨论】:

    标签: javascript html css toggle darkmode


    【解决方案1】:

    如果您在单击输入时查看控制台,您会看到它触发了两个单击事件,一次有效地切换了两次。您可以在changeMode() 中添加console.log(event) 以准确查看正在触发的事件(标签点击输入点击)。快速解决方法是将其更改为在输入更改时触发,而不是父标签单击:

    <label class = "switch">
       <input onchange="changeMode()" type = "checkbox" checked>
       <span class = "slider round"> </span>
    </label>
    

    【讨论】:

      【解决方案2】:

      您的问题实际上是在问如何用 js 更新 css 变量?

      下面是例子

       <script>
      // Get the root element
      var r = document.querySelector(':root');
      
      // Create a function for getting a variable value
      function myFunction_get() {
        // Get the styles (properties and values) for the root
        var rs = getComputedStyle(r);
        // Alert the value of the --blue variable
        alert("The value of --blue is: " + rs.getPropertyValue('--blue'));
      }
      
      // Create a function for setting a variable value
      function myFunction_set() {
        // Set the value of variable --blue to another value (in this case "lightblue")
        r.style.setProperty('--blue', 'lightblue');
      }
      </script> 
      

      添加var rs = getComputedStyle(r);就可以了

      source: w3school

      【讨论】:

        【解决方案3】:

        您是否注意到您的事件被触发了两次?您将事件侦听器放在带有输入复选框的标签上。单击标签就像单击复选框一样。所以你可以做的是改变 onclick 放在输入中。

        let color = "#141414";
        
        function changeMode() {
          
          console.log("Switch was toggled. Switching site color scheme...")
          
          let bg = document.querySelector(':root');
          
          // Should switch the value of 'color' from grey to white, and vice versa
          if (color === "#141414") { 
            color = "#ffffff"; 
          } else if (color === "#ffffff") {  
            color = "#141414"; 
          }
          console.log(color);
          bg.style.setProperty("--main2", color);
        
        }
        :root {
        
          --main1: #ffdb15;
          --main2: #141414;
        
        }
        
        html, body {
        
          background-color: var(--main2);
          
        }
        
        .switch {
          position: relative;
          display: inline-block;
          width: 60px;
          height: 34px;
          left: 20px;
          top: 20px;
        
        }
        
        .switch input {
          opacity: 0;
          width: 0;
          height: 0;
        }
        
        .slider {
          position: absolute;
          cursor: pointer;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          background-color: #ccc;
          -webkit-transition: .4s;
          transition: .4s;
        }
        
        .slider:before {
          position: absolute;
          content: "";
          height: 26px;
          width: 26px;
          left: 4px;
          bottom: 4px;
          background-color: white;
          -webkit-transition: .4s;
          transition: .4s;
        }
        
        input:checked + .slider {
          background-color: #5d00e2;
        }
        
        input:focus + .slider {
          box-shadow: 0 0 1px #5d00e2;
        }
        
        input:checked + .slider:before {
          -webkit-transform: translateX(26px);
          -ms-transform: translateX(26px);
          transform: translateX(26px);
        }
        
        .slider.round {
          border-radius: 34px;
        }
        
        .slider.round:before {
          border-radius: 50%;
        }
        <label class = "switch">
          <input type = "checkbox" checked onclick="changeMode()">
          <span class = "slider round"> </span>
        </label>

        【讨论】:

          【解决方案4】:

          你应该使用getComputedStyle来获取document.documentElement,然后你可以在条件中设置变量然后设置document.documentElement的样式 使用 setProperty

          getComputedStyle(element).backgroundColorelement.style.backgroundColor 有很大区别。第一个实际上会为您提供样式表中设置的 CSS,而后者将为您提供元素 HTML 标记中设置的内联样式。

          因此,您使用 getComputedStyle(element) 获得使用 CSS 文件中的变量设置的设置样式,然后通过条件运行并设置内联ROOT 使用 element.style.backgroundColor 元素设置为 document.documentElement

          let bg = document.documentElement;
          let input = document.getElementById('input')
          
          function changeMode() { 
            let color = '';
            currentStyle = getComputedStyle(document.documentElement).backgroundColor
            currentStyle === "rgb(20, 20, 20)" ? color = "rgb(255, 219, 21)" : color = "rgb(20, 20, 20)"      
            bg.style.setProperty("--main2", color);
          }
          
          input.addEventListener('click', changeMode)
          :root {
            --main1: #ffdb15;
            --main2: #141414;
          }
          
          html,
          body {
            background-color: var(--main2);
          }
          
          .switch {
            position: relative;
            display: inline-block;
            width: 60px;
            height: 34px;
            left: 20px;
            top: 20px;
          }
          
          .switch input {
            opacity: 0;
            width: 0;
            height: 0;
          }
          
          .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            -webkit-transition: .4s;
            transition: .4s;
          }
          
          .slider:before {
            position: absolute;
            content: "";
            height: 26px;
            width: 26px;
            left: 4px;
            bottom: 4px;
            background-color: white;
            -webkit-transition: .4s;
            transition: .4s;
          }
          
          input:checked+.slider {
            background-color: #5d00e2;
          }
          
          input:focus+.slider {
            box-shadow: 0 0 1px #5d00e2;
          }
          
          input:checked+.slider:before {
            -webkit-transform: translateX(26px);
            -ms-transform: translateX(26px);
            transform: translateX(26px);
          }
          
          .slider.round {
            border-radius: 34px;
          }
          
          .slider.round:before {
            border-radius: 50%;
          }
          <label class="switch">
            <input id="input" type="checkbox" checked>
            <span class="slider round"> </span>
          </label>

          【讨论】:

            猜你喜欢
            • 2015-01-17
            • 2015-05-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-12-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多