Skip to content

Instantly share code, notes, and snippets.

@robindotis
Last active December 19, 2022 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robindotis/d1b33ab257e5e6970765b8b865e94bf5 to your computer and use it in GitHub Desktop.
Save robindotis/d1b33ab257e5e6970765b8b865e94bf5 to your computer and use it in GitHub Desktop.
Really simple stylesheet switcher (RSSS)
/*
* RSSS: Really simple stylesheet switcher
*
* This script will generate buttons to switch stylesheets.
* It will use localstorage to store the users choice between sessions.
*
* Three variables need to be defined:
* - themeCss: Array of the available stylesheets. The first
* item in the array is the default style and
* should already exist in HEAD of the page as
* a LINK element. This ensures the default styling
* is loaded even without JavaScript.
* For each item in the array, except the first item,
* a link element with rel="alternate stylesheet"
* will be created
* For each item in the array a button will be created
* with an onclick event to trigger switching the stylesheet
*
* - themeName: Array containing the name for the buttons created as a
* result of themeCss. Must be the same length as themeCss.
*
* - themeId: The ID of the element within which the buttons should
* be created.
*
*/
var themeCss = ['default.css','high.css','plain.css','olden.css'];
var themeName = ['Default','High Contrast','Plain','Olden'];
var themeId = "themeSwitch";
function swapStyleSheet(th){
/* With help from these links:
https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
https://stackoverflow.com/questions/2694640/find-an-element-in-dom-based-on-an-attribute-value
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
*/
var styles = document.querySelectorAll('link[rel~="stylesheet"]');
var i;
/* insert correct rel attribute (alternate for inactive styles) */
for (i = 0; i < styles.length; ++i) {
/* returns true if the href contains any of the strings in the themes array */
/* this if statement ensures we only alter stylesheets used by the themes*/
if( themeCss.some(v => styles[i].href.includes(v))) {
if(styles[i].href.endsWith(th)) {
styles[i].rel = "stylesheet";
}
else {
styles[i].rel = "alternate stylesheet";
}
}
}
/* Disable the button for the currently selected style */
var btns = document.getElementById(themeId).querySelectorAll('button');
for (i = 0; i < btns.length; ++i) {
if(btns[i].onclick.toString().includes(th)) {
btns[i].setAttribute("disabled","");
}
else {
btns[i].removeAttribute("disabled");
}
}
localStorage.setItem("theme",th);
}
function createThemeSwitch(tc, tn, id) {
var dflt = document.querySelector('link[href*="' + tc[0] + '"]');
for(var i =0; i < tc.length; i++) {
/*Add in the alternate style sheets after default.css*/
if(i > 0) {
const lnk = document.createElement("link");
lnk.setAttribute('rel','alternate stylesheet');
lnk.setAttribute('href','/assets/css/' + tc[i]);
lnk.setAttribute('media','all');
dflt.after(lnk);
}
/*Create the button elements*/
const btn = document.createElement("button");
btn.setAttribute('type','button');
btn.setAttribute('onclick',"swapStyleSheet('/assets/css/" + tc[i] + "')");
btn.appendChild(document.createTextNode(tn[i]));
document.getElementById(id).appendChild(btn);
}
}
createThemeSwitch(themeCss, themeName, themeId);
if(localStorage.getItem('theme')) {
swapStyleSheet(localStorage.getItem('theme'));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment