How to enable dark theme with JS?

72 Views Asked by At

(I know that this question might be a dublicate but the other questions here didn't work for me, maybe because they're a little bit different than what I'm looking for) so, I'm trying to enable dark theme to all my html pages without the need to re-enable it in every page. this is the JS used. The difference here is that it switches between two css files, not just between selectors in one css file, like the other questions here.

function toggleTheme() {
    var theme = document.getElementsByTagName('link')[0];
    if (theme.getAttribute('href') == 'css/light.css') {
      theme.setAttribute('href', 'css/dark.css');
    } else {
      theme.setAttribute('href', 'css/light.css');
    }
  }

this is the link that the JS refers to:

<link id="theme" rel="stylesheet" type="text/css" href="css/light.css" />

I don't know if you need to know it or not but I'm using an svg element to enable the dark theme, not a button element. Please explain in details cuz I'm still new to JS. Thanks.

1

There are 1 best solutions below

5
Chris Barr On

Updated Answer

You can save a client-side preference with localStorage, however this might have some page flashes when it loads since you are going to be swapping out stylesheets. The best way to do this would be server-side, but here's how you can do it.

If you have this in your <head> by default...

<link id="theme" rel="stylesheet" type="text/css" href="css/light.css" />

Then I'd recommend this. Note that I've switch to use querySelector and I'm passing in the CSS ID selector for your element. This should be easier to read and more accurate since it selects by a unique ID instead of grabbing the first <link> element, which could break if you ever re-ordered them.

(()=>{
  const themeElement = document.querySelector('#theme');
  const defaultTheme = 'css/light.css';
  const darkTheme = 'css/dark.css';
  const storageKey = 'theme-preference';
  
  function setThemePref(url) {
    //update the tag attribute
    themeElement.setAttribute('href', url);
    //save the value in localstorage for the future
    localStorage.setItem(storageKey, url);
  }
  
  function toggleThemePref(){
    //call this method from your UI or whatever to switch themes and save the preference
    if (themeElement.getAttribute('href') === defaultTheme) {
      setThemePref(darkTheme);
    } else {
      setThemePref(defaultTheme);
    }
  }
  
  //run initially on page load - you could wrap this in a function if needed
  //get the saved preference from storage
  const userPref = localStorage.getItem(storageKey);
  //the retrieved value will be null if nothing was saved previously
  //no need to do anything if no preference was ever saved
  if(userPref != null) {
    setThemePref(userPref);
  }
})();

Original Answer

Your code seems to work just fine for me. I've changed nothing except that I've added a console.log to show what the element looks like after you change it.

function toggleTheme() {
  var theme = document.getElementsByTagName('link')[0];
  if (theme.getAttribute('href') == 'css/light.css') {
    theme.setAttribute('href', 'css/dark.css');
  } else {
    theme.setAttribute('href', 'css/light.css');
  }
  
  console.log(theme);
}
<link id="theme" rel="stylesheet" type="text/css" href="css/light.css" />

<button type="button" onclick="toggleTheme()">Toggle Theme</button>