Avoid flickering on the page due to inherited body background color when toggling themes by using JavaScript to immediately change the body background upon window load

I am currently working on implementing a theme toggle with local storage using JavaScript.

The issue I am facing is that when switching from a dark theme to a light theme and then navigating to a new page, the background blinks black briefly because the base theme's body background color is set to black. I have attempted to remove both backgrounds and handle them in JavaScript, but still encounter a blink effect either with the black or white background when transitioning between themes.

My theme toggle switches my site between dark and white modes. However, upon refreshing the page or navigating to a new one while in white mode, there is a quick flickering of the body's inherited black background color from the default dark theme before settling on the white theme. My goal is to achieve a seamless transition between themes and pages without any blinking of the background in black or white based on the respective theme colors.

Below is my current code:

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 the light mode and dark mode functions, I define the body background color.

Despite this, there seems to be a delay in updating the DOM or browser rendering, causing a black blink on every page refresh or click when switching to the white theme due to the initial black theme setting. Any suggestions for a proper workaround to address this issue would be greatly appreciated.

Thank you.

Answer №1

To ensure the background style is set before the body is rendered, one approach is to place the script at the end of the head section instead of waiting for the page to fully load with $(window).ready(). This way, the background style is ready when the body starts rendering.

Another consideration is that the body element may not exist when the script executes. In this case, you can use functions like lightmode() and darkmode() to dynamically create a style tag at the end of the head with the necessary properties for the background. Here's an example:

// Perform your checks 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") // Set color for light mode
}
darkmode() {
  applyBackgroundTheme("black") // Set color for dark mode
}

This method should provide a solution to your issue. Hope it helps in some way.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Storing email information using PHP, JQuery, and Ajax to a MySQL database

Here's what I have so far in my code: main.js file: $('#addButton').on('click', function() { var email = $('#userInput').val(); $.ajax({ type: "post", url: 'validation.php', success: function( ...

Challenges with encoding JSON data

This may seem like a basic issue, but I'm stuck and looking for some help. Let me explain what's going on. Here's the situation: I have a database request and I need to json encode the data retrieved from that request so I can use it in a J ...

How to handle a Vue element click event through programming

In my Vue instance, I am looking to have a response triggered by a click on an uploaded thumbnail. Utilizing the Vue package called FineUploader Vue with the template layout as outlined in the documentation (refer to end of question). After uploading an i ...

Utilizing JQuery to fetch variables from a different webpage

Seeking assistance with this code. In my Rails project, I've implemented a fixed header. Here is one of the links: <li><%= link_to "Your Address Book", user_path(current_user), :class => 'random_number' %></li> Furthe ...

Using jQuery to determine if a parent checkbox has been clicked when its child checkbox is checked or

check1 = $('.myCheckBox1'); check1Parent = $('.myBarElems:nth-child(4)'); check1Parent.click(function() { if(check1.is(':checked')){ check1.prop('checked', false); }else{ check1.prop('che ...

The function is defined, but it cannot be set to null

Having trouble understanding this error message "Cannot set properties of null." I'm attempting to update the innerHTML with the output text from four functions that my button triggers. However, it seems to be stopping at the first function now even t ...

Having trouble with the initial tap not being recognized on your mobile browser?

When using mobile web browsers (specifically chrome and firefox on iOS), I am experiencing an issue where the hamburger menu does not trigger when tapped for the first time. For a simplified version of the HTML/CSS/JS code, you can check it out at: https ...

Using MongoDB to efficiently paginate results

Currently engaged in the development of a web application using MongoDB, which dynamically populates pages with content on the browser. Familiar with two different methods for paging (referenced here: ): 1) Utilizing .skip() + .limit() 2) Implementing . ...

Stop the duplication of downloading JavaScript files

When it comes to my website, I have incorporated sliders that stream videos from Vimeo. Upon running a check on GTMetrix, I noticed an overwhelming number of http requests. Looking at the waterfall, I discovered numerous duplicate downloads of javascript, ...

Exiting a Node.js process using process.exit() may not result in a clean exit, especially when dealing with asynchronous file writing

tl;dr: When using asynchronous fs.writeFile in Node.js from asynchronous events or loops and then calling process.exit(), the files are successfully opened but the data fails to be flushed into the files. It appears that the callbacks given to writeFile d ...

Setting up Npm Sequelize Package Installation

Could use some help with setting up Sequelize. Here's the current status: https://i.sstatic.net/MQH1I.jpg ...

AngularJS: enhancing $http with custom functionality

I am facing an issue with my simple controller, which looks like this: function MyController($scope, $http) { ... $http.post(url).success(function(data) { console.log(data) }); } MyController.$inject = ['$scope', &ap ...

React is unable to maintain the list during route transitions

I have been working on a project where I input user information into a form and upon submission, it displays the data in a table on the same page. Everything works fine initially, but when I navigate back to the form page after visiting the Home page, the ...

Issues encountered when trying to use default color classes in Tailwind CSS

I'm currently working on a React project that utilizes the Tailwind CSS Framework. To integrate Tailwind into my React app, I used NPM to install it in the following way: npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p After i ...

Is there a way to change the source attribute instead of the text content?

Is there a way to update the src attribute instead of the text content? For instance, if I want a winter image, title, and description for December, and a summer image, title, and description for August. How can I store images in this JSON format and use t ...

A step-by-step guide on adding a table with colored icons (red, green, and blue) to an HTML page using jQuery

I'm working on a project that requires designing an HTML page with three tables containing images, along with a compare button. Initially, only two tables are visible upon page load, but when the user clicks the compare button, the third table should ...

Differences Between JavaScript Binding and Anonymous Functions

I came across this code in the mongoose-deep-populate library async.parallel([ User.create.bind(User, {_id: 1, manager: 2, mainPage: 1}), Comment.create.bind(Comment, {_id: 3, user: 1}), ... ], cb) which utilizes Function.prototype.bind to make ...

Slide inside a div to move content

Check out the script I've been experimenting with for bringing in a menu from the left: Demo Fiddle To make this work, the sliding DIV needs to not only appear on the left but also push the 'left panel' and 'right panel' accordin ...

Utilizing React Hooks and Firebase Firestore onSnapshot: A guide to implementing a firestore listener effectively in a React application

SITUATION Picture a scenario where you have a screen with a database listener established within a useEffect hook. The main goal of this listener is to update a counter on your screen based on changes in the database: (Utilizing the useEffect hook without ...

axios is refusing to update or be uninstalled

Despite my efforts to update the axios package, it stubbornly refuses to upgrade to the latest version. I'm currently running a node server using pm2 I've attempted the following: npm uninstall axios npm i axios and even npm update axios ...