Jump to content
Eric Roth

Toggle Dark Mode and Web Storage

Recommended Posts

Hello,

I found this helpful: "How To - Toggle Dark Mode" (https://www.w3schools.com/howto/howto_js_toggle_dark_mode.asp) and this one: "HTML5 - Web Storage" (https://www.w3schools.com/html/html5_webstorage.asp).

Can anyone help to combine these two? I successfully implemented the "How To - Toggle Dark Mode" but fail to combine Local Storage together with it.

Thanks!

Cheers, Eric

Share this post


Link to post
Share on other sites

Hi there,

Can you give us the code that isn't working? Do you have an idea on where exactly its gone wrong?

Share this post


Link to post
Share on other sites

Hi Funce,

Here is the JS code, I'm working with:

<?php
add_action( 'wp_footer', function() { ?>
    <script>
jQuery(document).ready(function ($) {
var change_mode_button_is_visible = false;
var scroll_distance = 50;
var $change_mode_button = $('<div class="change-mode-button" title="Toggle Mode"><img src="https://ericroth.org/wp-content/uploads/Home/Mode.png" alt="Toggle Mode" width="20" height="20" class="aligncenter wp-image-63135" /></div>');
// inject the button, so you don't have to create the button in any templates
$change_mode_button.appendTo('body');
$(window).scroll(function() {
  // called on every scroll action
  if ($(window).scrollTop() > scroll_distance && !change_mode_button_is_visible) {
    change_mode_button_is_visible = true;
    $change_mode_button.fadeIn(200);
  } else if ($(window).scrollTop() < scroll_distance && change_mode_button_is_visible) {
    change_mode_button_is_visible = false;
    $change_mode_button.fadeOut(200);
  }
});
// toggle mode if button is clicked
$('.change-mode-button').click(function() {
    changeMode();
  });
function changeMode() {
   var element = document.body;
   element.classList.toggle("dark-mode");
    
    // Store
   localStorage.setItem("changeMode", "dark-mode");
    // Retrieve
   document.body = localStorage.getItem("changeMode");
    
}
});
    </script>
<?php });

The .css class is dark-mode:

.dark-mode {

...

}

Probably you can see, I'm not an expert at all - but at least managed to get the toggle function working: https://ericroth.org/dummy/

I really would appreciate very much if someone could point me into the right direction with this web storage issue.

Thanks,

Eric

Share this post


Link to post
Share on other sites

Oh I see. Well for this you'll need two parts.

You'll need the part which saves the state of the dark-mode. This will occur when you press the 'dark-mode' button.

function changeMode() {
  var element = document.body;
  element.classList.toggle("dark-mode");
  localStorage.setItem("changeMode", element.classList.contains("dark-mode");
}

Then when the page loads, you'll need to retreive the dark-mode state and apply it.

var element = document.body;
if(localStorage.setItem("changeMode")) {
  //dark-mode is on
  element.classList.add("dark-mode");
}
//If dark-mode isn't on, the natural state of the page 
//doesn't need to be changed.

 

 

As an aside, I couldn't really stay on your website for more than about fifteen seconds, due to all the movement in the page giving me motion sickness. You may want to tone that down, probably on the backgrounds.

Edited by Funce
Grammar

Share this post


Link to post
Share on other sites

Hi,

Many thanks for your reply and help. I worked with your code but it doesn't function.

I also tried all kinds of varieties, I could think of - no luck. The latest, I have now in the script is this:

// toggle mode if button is clicked
$('.change-mode-button').click(function() {
    changeMode();
  });
function changeMode() {
  var element = document.body;
  element.classList.toggle("dark-mode");
  localStorage.setItem("changeMode", element.classList.contains("dark-mode"));
  if(localStorage.setItem("changeMode")) {
  element.classList.add("dark-mode");
  }
}

What could possibly still be wrong?

Thanks,

Eric

P.S. You are definitely right with your input about the site a bit being overloaded (evaluating the limits of what all can be done by me has just been tempting, I guess...:-). I'm in the process of cleaning that up though but currently, I'm rather "obsessed" with this local storage thing. Once that's up and running, I shall tone it down as suggested.

Share this post


Link to post
Share on other sites

I should specify that the two sets of code should be separate, though I do notice an error in the code that I gave you (apologies for that) I'll do my best to clarify.

So my changeMode function should still be accurate, just need to move the changeMode Loading

This should be your program flow

  • Page Load
    • Load the value of changeMode
  • Press Change Mode Button
    • Toggle Class
    • Save value of change mode

And I'll amend my code to be correct.

var element = document.body;
if(localStorage.getItem("changeMode")) {
  //Note getItem rather than setItem
  //dark-mode is on
  element.classList.add("dark-mode");
}
//If dark-mode isn't on, the natural state of the page 
//doesn't need to be changed.

Now the code above needs to be run when the page loads, are you able to figure that part out?

 

In addition, you can use the Forum's Code Block feature to post snippets of code so that they are readable. Check it out.
XcQfW3F.png

Edited by Funce
Code Block message

Share this post


Link to post
Share on other sites

That helped - you are the best, thank you!

A small "problem" though (of which I think, I understand the logic of the code and perhaps, this could not be solved with the way the toggle function is set up on the site). What happens now is that as soon as one toggles the mode from normal to dark, it stays in the dark mode. I mean, one can toggle back to the normal mode, yes - but when refreshing the page or moving on to another page, it loads in the dark mode again.

Since this is local storage, the above happens even after closing and re-opening the browser (and thereby cleaning out all the cookies, storage and stuff). So, I switched to session storage instead. This way, a returning visitor / new browser session gets the site shown in normal mode initially and has one shot only to toggle the mode for the remaining browser session.

Sorry, for the English as I'm not a native speaker but I hope, you know what I mean. I ended up with this code and this is by far sufficient for my needs - so thank you once again for your help:

// toggle mode if button is clicked
$('.change-mode-button').click(function() {
    changeMode();
  });
function changeMode() {
  var element = document.body;
  element.classList.toggle("dark-mode");
  sessionStorage.setItem("changeMode", element.classList.contains("dark-mode"));
}
  var element = document.body;
  if(sessionStorage.getItem("changeMode")) {
  element.classList.add("dark-mode");
}

Cheers, Eric

P.S. As I am new to this forum... is there a possibilty (or is it expected at all) to mark this topic as solved - and perhaps rate your help?

Share this post


Link to post
Share on other sites

On load of document you should check if sessionStorage is set, if set, set class to currently held value, else set to a default value. What you are doing is setting to 'dark-mode' whatever state its in on page load.

Share this post


Link to post
Share on other sites

So, uh, I did a bit of digging to look into this, and it seems that setItem stores a string, so getItem returns a string and a non-empty string is always truthy. Dang it.

If you change the getItem code to the following

var element = document.body;
if (localStorage.getItem("changeMode") == "true") {
  //dark-mode is on
  element.classList.add("dark-mode");
}

You should have a bit more luck with this.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...