正文 CSS 未使用 .setProperty() 更新

Body CSS not updating with .setProperty()

我正在尝试在网站上启用暗 mode/light 模式功能,我在其中使用 .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变量上,还是程序在切换值时没有更新页面主体本身?

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

你的问题实际上是问如何用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

您是否注意到您的事件被触发了两次?你把你的事件监听器放在一个标签上,里面有一个输入复选框。单击标签就像单击复选框一样。因此,您可以做的是更改要放入输入中的 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>

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

getComputedStyle(element).backgroundColor[=有很大区别53=]。第一个实际上会为您提供样式 sheet 中的集合 CSS,而后者将为您提供元素 HTML 标签中的内联样式集。

因此,您使用 getComputedStyle(element) 获得使用 CSS 文件中的变量设置的设置样式然后 运行 通过您的条件并使用 element.style.backgroundColor 设置 ROOT 的内联,其中元素设置为 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>

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

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