Using Cookies to Retain Stylesheet Preference Across Website

Using cookies to retain stylesheet preference across website

I would use HTML 5 local storage to store the CSS filename:

Store the user's selection with a function like:

    function storeStyleSheet(styleSheetKey, StyleSheetName){
localStorage.setItem(styleSheetKey, StyleSheetName);
}

And pull and use the stored CSS, if there is one:

    function setStoredStyleSheet(styleSheetKey){
var styleSheet = localStorage.getItem(styleSheetKey);
if(!(styleSheet=='undefined' || styleSheet==undefined) ){
swapper(styleSheet);
}
else{
swapper('css/stylesheetalternate.css');
}
}

I have found HTML 5 local storage to be easier to use than cookies. I have not had any problems using localStorage on any browser. And the interface is intuitive; just be aware that if the file/keyname was never stored before, it will return 'undefined' or undefined. There is also no automatic timeout with localStorage.

Change Stylesheet and save it to Cookies / Local storage

At load event of window define a variable to store reference to Blob URL. If localStorage has key, for example, "styles", get css from localStorage, create a Blob with localStorage.getItem("styles") set as element of iterable at first parameter, type set to "text/css". Pass Blob to URL.createObjectURL() to set at value of #design .href. Else, filter document.styleSheets for .href which matches sheet parameter at swapStyleSheet call, create get .cssText from .rules property lookup, set as Blob, perform above described procedures.

window.onload = function() {
let blob, url;

function setStyle() {
var sheet = localStorage.getItem("styles");
blob = new Blob([localStorage.getItem("styles")], {type:"text/css"});
url = URL.createObjectURL(blob);
document.getElementById("design").setAttribute("href", url);
}

if (localStorage.getItem("style") != null) setStyle();

function swapStyleSheet(sheet) {

var rules = Array.prototype.filter.call(document.styleSheets, function(styles) {
return styles.href.indexOf(sheet) !== -1
})[0].rules;

for (var i = 0, css = ""; i < rules.length; i++) css += rules[i].cssText;

if (url) URL.revokeObjectURL(url);

localStorage.setItem("styles", css);

setStyle();

}
}

Keep website theme the same.. cookies?

If you're using all javascript and don't have any serverside code to work with, here's a JS example to set and read a cookie:

Add this function to your JS, then run it when the theme is changed:

function set_theme(name){
document.cookie='sel_theme='+name+';';
}//so, run set_theme('whatevername'); when it is set by the user

To read the cookie and set the theme on page load (using jQuery or similar $(document).ready() would be better than onload, though, but here's a straight js/dom example)

 window.onload=function(){
var cookie_pos=document.cookie.indexOf('sel_theme=');//locate value in cookie
if(cookie_pos!=-1){//if string was found
var cookie_flavor=substr(cookie_pos+10,document.cookie.indexOf(';',cookie_pos));//extract the value of the cookie
/*then run your already existing change theme function using the extracted name*/
}

How to set user preference via cookies for dark mode?

You can use the localStorage api (reference):

// Code to save setting
localStorage.setItem('darkTheme', '1'); // Here you can put any string you want, I just chose 2 understandable ones

// Code to retrieve the setting
localStorage.getItem('darkTheme');

Edit: implementing the request of the comment down here

You can simply loop through the components of your page and set their style to match the selected theme (although loading different css is more performant and advised, it would require editing a good chunk of your current code)

const theme = localStorage.getItem('darkTheme');

if (theme) {
// Runs only if darkTheme is set to 1, or any truthy value
// (see https://developer.mozilla.org/en-US/docs/Glossary/Truthy for reference)

document.querySelector('body').classList.add('isdark');
clicks++; // This is to keep your theme switcher working: if the page starts dark and the user clicks to change the theme you want to revert back to light
}

To incorporate this in your code:


/* Dark Mode */
var clicks = 0;

const theme = localStorage.getItem('darkTheme');

if (theme) {
// Runs only if darkTheme is set to 1, or any truthy value
// (see https://developer.mozilla.org/en-US/docs/Glossary/Truthy for reference)

document.querySelector("body").classList.add("isdark");
clicks++; // This is to keep your theme switcher working: if the page starts dark and the user clicks to change the theme you want to revert back to light
}

$('#modetog').click(function() {
if (clicks % 2 === 0){
document.querySelector('body').classList.add('isdark');
localStorage.setItem('darkTheme', '1');
} else{
document.querySelector('body').classList.remove('isdark');
localStorage.setItem('darkTheme', '0');
}
++clicks;
});

Read a cookie when implementing inside of another function

Here's a set of plain javascript cookie functions that you can use from any function. So, to your question, you can call readCookie("username") from your function (or read any other cookie value):

// createCookie()
// name and value are strings
// days is the number of days until cookie expiration
// path is optional and should start with a leading "/"
// and can limit which pages on your site can
// read the cookie.
// By default, all pages on the site can read
// the cookie if path is not specified
function createCookie(name, value, days, path) {
var date, expires = "";
path = path || "/";
if (days) {
date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
expires = "; expires=" + date.toGMTString();
}
document.cookie = name + "=" + value + expires + "; path=" + path;
}

function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
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) {
createCookie(name, "", -1);
}

Cookie values are not getting applied unless page is reloaded again

You are setting cookie with js but reading it with php, so you need to refresh since php is serverside. When you set cookie reload the page and you should see changes

How would I store user theme preferences across multiple pages?

When using localStorage you opperate with setItem and getItem, you can read more about the examples of how to use localStorage here https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage#examples.

If you want to get/set localStorage item you would use something like this:

// Creates/sets the localStorage item of "theme" to "dark"
localStorage.setItem("theme", "dark")

// Gets the localStorage item named "theme", and checks if the value is "dark"
const isDarkMode = localStorage.getItem("theme") === "dark"

One way of implementing this could be something like this:

// DOM elements
const toggle = document.querySelector(".toggle");
const html = document.querySelector("html");

// Check the browser preferred color scheme, and sets the defaultTheme based of that
const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
const defaultTheme = prefersDarkMode ? "dark" : "light";
const preferredTheme = localStorage.getItem("theme")

// Check if the localStorage item is set, if not set it to the default theme
if (!preferredTheme) {
localStorage.setItem("theme", defaultTheme);
}

// Sets the theme of the site either the preferredTheme or the defaultTheme (based on localStorage)
html.dataset.theme = preferredTheme || defaultTheme;

// Theme toggle handler
toggle.addEventListener("click", () => {
// Check if the saved theme in localStorage is "dark"
const isDarkTheme = localStorage.getItem("theme") === "dark";
// Chooses the opposite theme of the current selected one
const newTheme = isDarkTheme ? "light" : "dark"
// Changes the theme to the newTheme
localStorage.setItem("theme", newTheme);
html.dataset.theme = newTheme;
});

You would then need to change your data attributes in the css to check for the theme and not true or false like this:

html[data-theme="light"]{...}
html[data-theme="dark"] {...}


Related Topics



Leave a reply



Submit