Hello! It’s been years since I’ve properly used CSS and HTML, and I’ve barely touched Javascript before, so I’m pretty rusty on the easy things.
I’m trying to have a button in my sidebar that, when pressed, will toggle between light mode/dark mode, essentially to invert the body’s text color and background color. I’ve assigned each of those to a variable in :root, so they’re easy to access; I just don’t know how to actually go about making a function to swap between two themes on a button press. I know it’s something-something-Javascript, but that’s about all I’ve got.
I’ve tried to work with the Sugarcube Setting.API, but can’t seem to wrap my head around it – I’ve gathered that I’ll be needing to make two seperate body classes in my stylesheet and find a way to swap between them.
Any help would be appreciated for this rookie! Thanks!
(and then maybe set it to “light” or some other value when you toggle it the other way)
Hook it up to the click event on the button with addEventListener, and probably use document.documentElement.getAttribute("data-theme") to see which state it’s currently in.
I don’t know if that’s enough to get you started, or if more details would be helpful…?
Well, stubborness won out and I wound up trying to cobble something together with good ol’ W3Schools samples. While it may not be working, I think I’m closer…? Here’s where I’m at.
makar, that is more-or-less the approach I used for QuestJS. All the real work is done in CSS. It does make the style sheet more complicated if there are a lot of changes, but still the easiest way I suspect. If you need to have other elements change, do something like this:
The first bit sets the default for my class input-text. The second gets used when the body element (or any parent element) has the dark-mode class - so no need to change the JavaScript.
Hmm…I always forget the details of visibility in SugarCube/JavaScript. You could try window.myFunction = function() { ...etc... }.
Most people don’t use the onclick attribute these days, which for a single-developer project is largely just a fashion trend, but the more current thing would be to give the button an ID: <button id="toggle-theme"> and then add the event handler with javascript, maybe like:
Even if it’s a bit more cumbersome, I’m favoring the simple toggle button on the sidebar rather than another submenu.
I’m thinking that the function, as-is, works. There’d just need to be a check in passageHeader – if, say, a boolean var named lightMode is false, then run “myFunction”. The button’s onClick would set the bool lightMode to the opposite of whatever it is (I think that’d be something like lightmode = !lightMode ?).
I just… admittedly, have no clue how to write that actual code and implement it. Would someone be able to adapt the pseudocode into something functional?
Using special passages that way is not encouraged, although I will admit that knowing that it’s not best practice has not stopped me from doing this exact thing in the past.
But if you really want to do it this way, you can declare the variable $lightMode in StoryInit and then put the following in your StoryMenu passage (or StoryCaption as you currently have it, but this is the intended use of StoryMenu):
It really wasn’t a big effort—like I said, I’ve done dark mode this way myself, so I only had to tweak my own code/markup a little. Glad it was helpful!
(If anyone has a single-click/no-menu solution that doesn’t involve unrecommended hacky use of special passages, though, I would also love to know about it!)
Whoops, sorry, that’s an artifact of me messing around a bit trying to do the whole thing in JS (just because I had the impression that that was what OP wanted) before deciding that there was no need to reinvent the wheel. Thanks for pointing it out—I’ll edit my comment.