0

I've seen many solutions, but I just don't know how to make them work. This is my code.

const modeButton = document.getElementById('light-dark-btn');
const metroButton = document.getElementById('metro-button');
const body = document.body;
const slider = document.getElementsByClassName('slider');


modeButton.addEventListener('click', ()=> {
    let bgColor = document.body.style.backgroundColor
    if(bgColor == 'rgb(230, 230, 230)' || !bgColor){
        document.body.style.backgroundColor = 'rgb(18,18,18)';
        document.body.style.color = 'rgb(230,230,230)';
        document.cookie = "darkMode=true";
    }else if(bgColor == 'rgb(18, 18, 18)'){
        document.body.style.backgroundColor = 'rgb(230,230,230)';
        document.body.style.color = 'rgb(0,0,0)';
        document.cookie = "darkMode=false";
    }
})


body.addEventListener('load', ()=> {
    var darkMode = getCookie("darkMode");
    if(darkMode == "true"){
        body.style.backgroundColor = "rgb(18, 18, 18)";
    }
    if(darkMode == "false"){
        body.style.backgroundColor = "rgb(230, 230, 230)";
    }
})

Trying to make the state of a checkbox button stay the same when changing pages.

  • 2
    Checking CSS properties directly is [best avoided](/q/55071684/4642212), especially for color values. Instead, a CSS class should be used, e.g. `body { background: rgb(230, 230, 230); color: rgb(0, 0, 0); } body.dark { background: rgb(18, 18, 18); color: rgb(230, 230, 230); }`; then [`document.body.classList.contains("dark")`](//developer.mozilla.org/en/docs/Web/API/Element/classList) to check for its existence, `document.body.classList.toggle("dark", condition)` for setting the class iff `condition` is true, etc. – Sebastian Simon Nov 23 '22 at 19:52
  • Note that there are [much better alternatives](/q/14028959/4642212) to a `load` listener, like `type="module"`, `defer`, or `DOMContentLoaded`. – Sebastian Simon Nov 23 '22 at 22:05

1 Answers1

0

You didn't say how your script is being loaded into the page, but it's tricky to set on event listener for the body's load event. Here's an example:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
      function onBodyLoadFromAttr () {
        console.log('bodyload-fromAttr')
      }
      console.log('setting bodyload1');

      // never actually executes:
      document.body.addEventListener('load', ()=>console.log('bodyload1'));
    </script>
  </head>
  <body onload="onBodyLoadFromAttr()">
    <script type="text/javascript">
      console.log('setting bodyload2');

      // never actually executes:
      document.body.addEventListener('load', ()=>console.log('bodyload2'));
    </script>
  </body>
  <script type="text/javascript">
    console.log('setting bodyload3');

      // never actually executes:
    document.body.addEventListener('load', ()=>console.log('bodyload3'));
  </script>
</html>

Of the four event listeners, only the one set using the onload attr will actually fire. A better way is to use document.readyState and the DOMContentLoaded event, like this:

if (document.readyState !== 'loading') {
  setBodyColor();
} else {
  document.addEventListener('DOMContentLoaded', setBodyColor);
}

Another possible issue is with cookies. You didn't include the getCookie function, but in general, cookies can be fiddly and a pain to deal with (the API is not simple, cookies might be disabled, extensions might be messing with them, etc.). If you don't need to send the data to a server with every request, which seems like the case for a user's color preference, you're usually better off using localStorage:

const modeButton = document.getElementById('light-dark-btn');
const body = document.body;

modeButton.addEventListener('click', () => {
  let darkMode = localStorage.getItem('darkMode');
  console.log({ oldDarkMode: darkMode })
  localStorage.setItem('darkMode', darkMode !== 'true');
  console.log({ newDarkMode: localStorage.getItem('darkMode') })
  setBodyColor();
});

function setBodyColor () {
  if (localStorage.getItem('darkMode') === 'true') {
    body.style.backgroundColor = 'rgb(18, 18, 18)';
    document.body.style.color = 'rgb(230,230,230)';
  } else {
    body.style.backgroundColor = 'rgb(230, 230, 230)';
    document.body.style.color = 'rgb(0,0,0)';
  }
}

if (document.readyState !== 'loading') {
  setBodyColor();
} else {
  document.addEventListener('DOMContentLoaded', setBodyColor);
}
CCC
  • 151
  • 6