How do I use cookies to remember a button toggle or class in html?

Viewed 1083

How can I use cookies to remember whether dark mode is turned on and keep it active?

Here's my code:

$(".inner-switch").on("click", function() {
  if ($("body").hasClass("dark")) {
    $("body").removeClass("dark");
    $(".inner-switch").text("OFF");
  } else {
    $("body").addClass("dark");
    $(".inner-switch").text("ON");
  }
});
body {
  font-family: sans-serif;
  font-size: 1.125rem;
  display: flex;
  flex-direction: column;
  max-width: 50rem;
  margin: 0 auto;
  padding: 0 0.9375rem;
}

small {
  font-style: italic;
}

article {
  display: flex;
  flex-direction: column;
}

img {
  max-width: 100%;
  display: block;
  align-self: center;
}

.switch {
  align-self: flex-end;
  margin: 0.9375rem;
}

.inner-switch {
  display: inline-block;
  cursor: pointer;
  border: 1px solid #555;
  border-radius: 1.25rem;
  width: 3.125rem;
  text-align: center;
  font-size: 1rem;
  padding: 0.1875rem;
  margin-left: 0.3125rem;
}

.dark,
.dark * {
  background-color: #222;
  color: #e6e6e6;
  border-color: #e6e6e6;
}
<div class="switch">Dark mode:
  <span class="inner-switch">OFF</span>
</div>
<h1 class="title">Lorem ipsum dolor sit amete</h1>
<article>
  <h1>consectetur adipiscing elit.</h1>
  <p><small>Morbi hendrerit accumsan vulputate.m</small></p>
  <p>...</p>
</article>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js">
</script>

2 Answers

You can set cookies with plain javascript using document.cookie. Regarding your example code I'd recommend moving the darkMode functionality (enable/disable) in separate functions. Then read the cookie value when the pageload finished and call the functions depending on the cookie value.


Implement cookie logic

function setCookie(name,value,days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days*24*60*60*1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "")  + expires + "; path=/";
}
function getCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    // the following code allows multiple cookie values and splits them apart
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}
function eraseCookie(name) {   
    document.cookie = name+'=; Max-Age=-99999999;';  
}

DarkMode functionality in separate functions

function enableDarkMode() {
    $( "body" ).addClass( "dark" );
    $( ".inner-switch" ).text( "ON" );
    setCookie('darkMode',"1",7);
}

function disableDarkMode() {
  $( "body" ).removeClass( "dark" );
  $( ".inner-switch" ).text( "OFF" );
  setCookie('darkMode',"0",7);
}

Button click-event using the darkMode-functions

$( ".inner-switch" ).on("click", function() {
    if( $( "body" ).hasClass( "dark" )) {
      disableDarkMode();
    } else {
      enableDarkMode();
    }
});

Read the cookie when the page has finished loading (plain js)

document.addEventListener("DOMContentLoaded", function(){
  var darkMode = getCookie('darkMode');
  if (darkMode == "1") {
      // use darkmode
      enableDarkMode();
  } else {
      // no darkmode
      disableDarkMode();
  }
});

While Jonathan's answer does answer your question well, I do want to show how this can also be done with localStorage, as a comment has pointed out as a potential solution

$(document).on('load', () => {
    if (localStorage.getItem('dark-mode') === 'true') {
        $('body').addClass('dark')
        $('.inner-switch').text('OFF')
    }
});

$('.inner-switch').on('click', () => {
    let $body = $('body');
    let $switch = $('.inner-switch');

    if ($body.hasClass("dark")) {
        localStorage.setItem('dark-mode', 'false');
        $body.removeClass("dark");
        $switch.text("OFF");
    } else {
        localStorage.setItem('dark-mode', 'true');
        $body.addClass("dark");
        $switch.text("ON");
    }
});

This is a little simpler to implement than cookies, and will give you similar persistence

Related