javascript - How to stop light mode flickering to darker background on page load - Stack Overflow

So I have a bit of script for toggling between light and dark modes on my site. The dark mode is the de

So I have a bit of script for toggling between light and dark modes on my site. The dark mode is the default. Problem is, whenever the light mode is toggled on, with every page load it flickers to the dark mode for just a second before loading the light mode. I would really like it to not do this and super appreciate any help you all can give. Thanks in advance!

My Code is as follows:

if (localStorage['blackout']) {
 if (Number(localStorage['blackout']) == 1) {
$('BODY').addClass('blackout');
 } else {
  $('BODY').removeClass('blackout');
 }
} else {
  localStorage['blackout'] = 0;
  $('BODY').removeClass('blackout');
}
$('BODY').show();
$('#boToggle').on('click', function(){
  if (Number(localStorage['blackout']) == 0) {
      localStorage['blackout'] = 1;
$('BODY').addClass('blackout');
  } else {
      localStorage['blackout'] = 0;
$('BODY').removeClass('blackout');
 }
});

So I have a bit of script for toggling between light and dark modes on my site. The dark mode is the default. Problem is, whenever the light mode is toggled on, with every page load it flickers to the dark mode for just a second before loading the light mode. I would really like it to not do this and super appreciate any help you all can give. Thanks in advance!

My Code is as follows:

if (localStorage['blackout']) {
 if (Number(localStorage['blackout']) == 1) {
$('BODY').addClass('blackout');
 } else {
  $('BODY').removeClass('blackout');
 }
} else {
  localStorage['blackout'] = 0;
  $('BODY').removeClass('blackout');
}
$('BODY').show();
$('#boToggle').on('click', function(){
  if (Number(localStorage['blackout']) == 0) {
      localStorage['blackout'] = 1;
$('BODY').addClass('blackout');
  } else {
      localStorage['blackout'] = 0;
$('BODY').removeClass('blackout');
 }
});
Share Improve this question asked Jun 29, 2020 at 9:39 Charmaine SimpsonCharmaine Simpson 411 silver badge2 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 5

Put your JS (the part reading from local storage and applying the class) in the <head> section, and add the class to the <html> tag, so that it get executed before the body is parsed and displayed.

You can try it with this simple working demo:

<html>
<head>
  <script>
    // Do this before the body gets parsed
    if (localStorage.getItem('darkmode') === '1') {
      document.documentElement.classList.add('darkmode');
    }
  </script>
  <style>
    .darkmode body { background: #222; }
    .darkmode .light-only { display: none; }
    html:not(.darkmode) .dark-only { display: none; }
  </style>
</head>
<body>
  <button id="darkToggle">
    Switch to
    <span class="dark-only">light</span>
    <span class="light-only">dark</span>
    mode
  </button>

  <script>
    document.querySelector('#darkToggle').addEventListener('click', function() {
      var wasDarkMode = localStorage.getItem('darkmode') === '1';

      localStorage.setItem('darkmode', wasDarkMode ? '0' : '1');
      document.documentElement.classList[wasDarkMode ? 'remove' : 'add']('darkmode');
    });
  </script>
</body>
</html>

In case anyone else is having this issue and this helps; my solution to this was to store the chosen theme in the user's session data, and then ensuring the correct class was applied when in the HTML.

Here is my JavaScript client code:

window.getTheme = function () {
    let theme = localStorage.getItem('theme');
    if (!["dark", "light"].includes(theme)) {
        theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    }
    return theme;
}
window.setTheme = function (theme) {
    if (theme) {
        localStorage.setItem('theme', theme);
        // You could use the fetch API here instead...
        axios.post('/theme', { theme });
    } else {
        theme = getTheme();
    }
    document.querySelector('body').classList.remove('dark', 'light');
    document.querySelector('body').classList.add(theme);
}

window.unsetTheme = function () {
    localStorage.removeItem('theme');
    setTheme();
}

window.matchMedia('(prefers-color-scheme: dark)')
    .addEventListener('change', e => {
        setTheme();
    });

setTheme();

I'm using Laravel in the back end, so here's a simple handler for the theme endpoint:

Route::post('theme', function () {
    $theme = request('theme');

    if (in_array($theme, ['light', 'dark'])) {
        Session::put('theme', $theme);
    }
})->name('theme');

Finally we then need to add this to the body in the main layout:

<body class="font-sans antialiased {{Session::get("theme")}}">

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745672172a4639471.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信