3
votes

I'm trying to make a theme toggle with local storage in javascript.

My problem: When change from the theme to dark to white and then clicking to a new page. The theme will blink dark really quickly because the base theme body bg is black. However, I've tried removing both backgrounds and implementing them in javascript but one or the other will still get a black blink on light theme, or a white blink or dark theme.

My theme toggles my site from dark to white. However, when you refresh or change pages to white it quickly blinks the body's inherited bg color of black from the black theme before sticking to the white one. I'm trying to make it so when you transition between themes and pages there's a seamless transition without the background blinking black or white on the respected theme colors.

Currently, I have my code as such:

function checkBG() {
  //REDUCE FLICKER ON PAGE CHANGE

      if(lightmodeON = true) {

        console.log('loading white bg');
      }

      if(lightmodeON = false) {

        console.log('loading black bg');
      }


  if(window.matchMedia('(prefers-color-scheme: dark)').matches && localStorage.themepref == 2 ) {
   darkmode();
   console.log("OS Setting DARK MODE");
  }

    if (window.matchMedia("(prefers-color-scheme: light)").matches && localStorage.themepref == 1 ) {
     lightmode();
     console.log("OS Setting LIGHT MODE");
   }

   if(window.matchMedia('(prefers-color-scheme: dark)').matches && localStorage.themepref == "undefined" ) {
    darkmode();
    console.log("OS Setting DARK MODE");
   }

   if (window.matchMedia("(prefers-color-scheme: light)").matches && localStorage.themepref == "undefined" ) {
    lightmode();
    console.log("OS Setting LIGHT MODE");
  }

};



$(window).ready(function($) {
  checkBG();

  $(window).scrollTop( $("#top").offset().top );
  $(document).scrollTop(0);


  if (typeof (Storage) !=="undefined") {
    if (localStorage.themepref == 1 ) {
      lightmode();
    }
    else {
      darkmode();
      localStorage.themepref = 2;
    }
  }

In light mode, and darkmode I set the body-bg color.

However, this doesn't catch the DOM or Browser quickly enough and on white every page refresh or page clicks blink black because the theme is originally black. How can I make a proper work around for this.

Thanks.

1

1 Answers

3
votes

One solution is to set the script in the end of head instead waiting to page to load using $(window).ready. Then it will set the background style ready before rendering body.

Another detail. Since body doesn't exist when the script runs, you can use lightmode() and darkmode() for creation of a style tag in the end of head containing the properties for background, like this:

// you make your checkings, and call lightmode() or darkmode()

function applyBackgroundTheme(color) {
    var css = "body { background: " + color + "; }",
    head = document.head || document.getElementsByTagName('head')[0],
    style = document.createElement('style');
    head.appendChild(style);

      style.type = 'text/css';
      if (style.styleSheet){
        style.styleSheet.cssText = css;
      } else {
        style.appendChild(document.createTextNode(css));
      }
    }

lightmode() {
  applyBackgroundTheme("white") // color for light mode
}
darkmode() {
  applyBackgroundTheme("black") // color for light mode
}

Hope it helps somehow.