steve0greatness,
created on Sunday, 4 February 2024, 06:24:39 (1707027879),
received on Monday, 6 May 2024, 02:55:37 (1714964137)
Author identity: Steve0Greatness <steve0greatnessiscool@gmail.com>
b2dc65fa96e42761f355714fb136c048d0221330
blog-posts/creating_a_theme_switch.md
@@ -1,47 +1,75 @@
--- title: Creating a simple theme switchertitle: Create a Theme Switchdate: 2021 Dec 08 updated: 2024 Feb 01updated: 2024 Feb 03--- This is a simple tutorial on how to make a simple theme switcher. ## Step 1: Creating the themesFirst step is to create the themes you'll want on your site. You may just want a light and dark mode, however, you may also want other themes. As an example: a clown theme that makes the page absurdly colorful, like a GeoCities site in the early 2000s. For these themes, you can use CSS variables set on the `html` parent tag(all other elements are considered children of `html`). Variables can be set in CSS using double hyphens followed by a sequence of text that can use numbers(but not at the start), letters(capital or lowercase), underscores, and hyphens; these variables can then be accessed within your text using the `var()` function with the name of the variable(including the starting hyphens). You can change out the CSS variables using different selectors on the `html` tag within the CSS, for me: I'm using the `[data-theme]` attribute; however, you can use classes if you want. Here is the CSS I wrote:The first step is to create the themes in your stylesheet, you can have as many as you want. Just make sure to remeber all their names within your CSS.## Step 2: Making an array```css html[data-theme=light] { background: #fff; color: #000; --buttonBackground: #fefefe; --buttonBorder: #ccc; --buttonColor: #001; } html[data-theme=dark] { background: #000; color: #fff; --buttonBackground: #101010; --buttonBorder: #333; --buttonColor: #fff; } html[data-theme=clown] { background: #f00; color: #00f; --buttonBackground: #050; --buttonBorder: #0a0; --buttonColor: #0f0; } button { background: var(--buttonBackground); border: var(--buttonBorder) solid 3px; color: var(--buttonColor); } ```This is why you need to remeber all their names within the CSS. You need to add them all to an array in your JS. Below is an example of an array containing some themes.Now we need to create a button that we will use to change the `[data-theme]` attribute. You (probably) already know what buttons are, so I won't go in depth about then. However: you will need to add an `[id]` to the button, this will come in play shortly.```jsconst themes = ["light", "dark", "gamer"]```html <button id="theme-switch">Switch Theme</button>``` ## Step 3: Switching themesNow, it is time to write the JavaScript. First, you'll want to make a constant with the themes you filled into your CSS, for me, that was `dark`, `light`, and `clown`. I'll name this `themes`. ```javascript const themes = ["light", "dark", "clown"]; ```This is the part you've been waiting for! The actual content switcher. It's surprisingly simple.We now need to query the <abbr title="Document Object Model">DOM</abbr> for our theme switch button. This can be done in 2 ways: `document.querySelector` or `document.getElementById`; personally, I prefer `querySelector`, as it allows you to write a CSS selector to get an element from the DOM, allowing for shorter, more digestible, code.First, get the index of the current theme usingWe have to add a click event to the button. This can be done in 2 ways within JavaScript: `addEventListener("click", ...)` and `onclick`. I personally like `addEventListener` more, so I'll use that. Within the `addEventListener` function, you need to put a function. This function will control the logic of our theme switch. I'll call this function `SwitchTheme`, to reflect it's functionality.```jslet currentTheme = themes.indexOf(document.documentElement.className).```javascript const ThemeSwitchButton = document.querySelector("#theme-switch"); ThemeSwitchButton.addEventListener("click", SwitchTheme()); function SwitchTheme() {}``` Then, use an if statement to see if it's more than or equal to the length of the array containing your themes.Explaining each part of this function as it's written out would take awhile, so instead, I'll add comments to the ends of each line giving a short explanation. Also, for the sake of shortness, I've placed `document.documentElement` inside the constant `HTML`, giving us access to the root element in the DOM(`html`).```jsif (currentTheme + 1 >= themes.length) {document.documentElement.className = themes[0];} else {document.documentElement.className = themes[currentTheme + 1]```javascript let CurrentTheme = themes.indexOf(HTML.dataset.theme); // Gets how far in the current theme is into the "themes" constant. if (CurrentTheme + 1 >= themes.length) { // Checks if it's at the end of the array, HTML.dataset.theme = themes[0]; // If so, reset at the start. return; // Ends the function here, preventing next bit of code from running.} HTML.dataset.theme = themes[CurrentTheme + 1]; // Goes to the next theme.``` Now just add a listener to the button(using [event listener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener), [getElement.onclick](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick), or [onclick](https://www.w3schools.com/TAgs/att_onclick.asp))## Final ProductIn the end, what you just made should look something like the iFrame below.Now we have a finished product. Here's the expected output:<iframe id="finalProduct" src="/blog-files/theme-change-final.html" style="border:none"></iframe> [See Code](/blog-files/theme-change-final.txt)
static/blog-files/theme-change-final.html
@@ -17,7 +17,7 @@
--buttonBorder: #333; --buttonColor: #fff; } html[data-theme=gamer] {html[data-theme=clown] {background: #f00; color: #00f; --buttonBackground: #050;
@@ -33,21 +33,21 @@
</head> <body> <button id="themeSwitch">Switch Theme</button><button id="theme-switch">Switch Theme</button>This is epic! <script type="text/javascript"> console.log("Changing theme")const themes = ["light", "dark", "gamer"];document.querySelector("#themeSwitch").addEventListener("click", function() {console.log("Changing theme")let curTheme = themes.indexOf(document.documentElement.dataset.theme);if (curTheme + 1 >= themes.length) {document.documentElement.dataset.theme = themes[0];return;const themes = ["light", "dark", "clown"]; const ThemeSwitchButton = document.querySelector("#theme-switch"); const HTML = document.documentElement; ThemeSwitchButton.addEventListener("click", SwitchTheme); function SwitchTheme() { let CurrentTheme = themes.indexOf(HTML.dataset.theme); // Gets how far in the current theme is into the "themes" constant. if (CurrentTheme + 1 >= themes.length) { // Checks if it's at the end of the array, HTML.dataset.theme = themes[0]; // If so, reset at the start. return; // Ends the function here, preventing next bit of code from running.} console.log("asfd")document.documentElement.dataset.theme = themes[curTheme + 1];})HTML.dataset.theme = themes[CurrentTheme + 1]; // Goes to the next theme. }</script> </body>
static/blog-files/theme-change-final.txt
@@ -17,7 +17,7 @@
--buttonBorder: #333; --buttonColor: #fff; } html[data-theme=gamer] {html[data-theme=clown] {background: #f00; color: #00f; --buttonBackground: #050;
@@ -33,21 +33,21 @@
</head> <body> <button id="themeSwitch">Switch Theme</button><button id="theme-switch">Switch Theme</button>This is epic! <script type="text/javascript"> console.log("Changing theme")const themes = ["light", "dark", "gamer"];document.querySelector("#themeSwitch").addEventListener("click", function() {console.log("Changing theme")let curTheme = themes.indexOf(document.documentElement.dataset.theme);if (curTheme + 1 >= themes.length) {document.documentElement.dataset.theme = themes[0];return;const themes = ["light", "dark", "clown"]; const ThemeSwitchButton = document.querySelector("#theme-switch"); const HTML = document.documentElement; ThemeSwitchButton.addEventListener("click", SwitchTheme); function SwitchTheme() { let CurrentTheme = themes.indexOf(HTML.dataset.theme); // Gets how far in the current theme is into the "themes" constant. if (CurrentTheme + 1 >= themes.length) { // Checks if it's at the end of the array, HTML.dataset.theme = themes[0]; // If so, reset at the start. return; // Ends the function here, preventing next bit of code from running.} console.log("asfd")document.documentElement.dataset.theme = themes[curTheme + 1];})HTML.dataset.theme = themes[CurrentTheme + 1]; // Goes to the next theme. }</script> </body>