Check out a free preview of the full Vanilla JavaScript Projects course

The "Dark Mode Switcher Solution" Lesson is part of the full, Vanilla JavaScript Projects course featured in this preview video. Here's what you'd learn in this lesson:

Anjana live-codes the solution to the Dark Mode Switcher exercise.


Transcript from the "Dark Mode Switcher Solution" Lesson

>> All righty, so, We may have noticed that there is a handy dandy pre-ided [LAUGH] script tag at the bottom of this HTML file where we can write the JavaScript we need to make this happen. So how, Did it feel to be just stretching our legs, messing with a page?

>> Felt pretty good.
>> All right, we're getting our feet wet. And again, the quick win category, I think it's important to start with some small wins. Or maybe not start, but continue to try to find those opportunities for the quick wins all the time because there's a lot of very slow losses.

So, [LAUGH] all righty, so hopefully, we've now got a input check box that actually does something. I'm going to walk you through how I solve this. But there's lots of different ways to Java a script. So [LAUGH] we're going to also have a chance, if folks have done it a different way, perhaps in one line of code, or in many more, we can share that with each other.

All right, we can grab that document element that we were talking about before with document.documentElement. And my handy-dandy, very smart, very large code editor is [LAUGH] helping me out with some suggestions. But, that's not a method it's a property. We're going to then be able to do stuff like doc.getAttribute data-theme to get the value of the currently set theme so I could capture that as something like currentTheme.

And if all goes well, we can log the value to the console just to check on what it is. All right, so now I see some output, dark. What's all this other stuff about vite? We're gonna talk about it later [LAUGH], this is not the console log you are looking for, Star Wars people?

No, just okay, we've got the currentTheme. Now we want to figure out what the new theme would be. So I'm gonna make a new variable newTheme. So it's either gonna be dark or light, the string, dark or the string light. And we want it to be the other one from what the current theme is.

[SOUND] I could declare a let variable so that I can change its value later. That's like newTheme. And then I could do a whole if currentTheme is dark, then newTheme should be light. But this is taking me forever. And I've had to use multiple lines of code, which for some reason developers are averse to.

So there is a shorter way to do that. Can anybody tell me what the shorter way to write an if else statement like this would be, yeah?
>> Ternary operator.
>> Ternary operator. Yes, so, this was mentioned briefly in JavaScript first steps, but in addition to doing a whole, if else, branching logic this way, we could replace this with, well, this is gonna be upset because I already declared newTheme.

But we can replace it with a ternary operator that's like condition, [SOUND] then this is the kind of if block, and then if not or else. So, in this case, our condition is currentTheme is dark and our if block is the value we want for newTheme is light.

So that means that is what this is going to evaluate to which is then going to be on the right hand side of the assignment operator equals. So that's what the value of newTheme is gonna be. And if it's not, then that means the currentTheme must be light, so we're going to want to assign the opposite value, in this case, dark, to the new Theme.

Okay, so now, I can do all of this. Fabulous, now, I could just, for example, change the value of this data-theme attribute once and for all with setAttribute, thank you VS Code, tab completion there. If you start typing something in VS Code and you have certain language settings enabled for JavaScript, it'll complete what it knows.

Is it always correct? Absolutely not. Does it help most of the time? Sure, okay, so I can set the attribute data-theme to the newTheme instead. So now if I run this, okay. So it's in light mode, so that's good, but this still doesn't do anything. And that's because I need an-

>> Event listener.
>> Event listener, exactly, so I am going to put all this fun little code in a function, which then I can pass as the handler function to the addEventListener. So, we're gonna need to attach this to the input, this check box input. So I can grab that with, I'm gonna call it toggle and it has that ID toggle.

So I can do document.getElementById toggle. And hopefully, let's just double check. Get the toggle, Input element which is, yes, what I am receiving here. Fabulous, so now I could do a toggle addEventListener. Drink coffee before programming if you're into that kind of thing. [LAUGH] The addEventListener, we're going to pass in the name of the event that we want to listen for.

In this case, it would be a, anybody know the name of the event that we'd wanna listen for? So like buttons, we can listen for clicks. But on input elements, we often listen for-
>> Change.
>> Change events, absolutely. And there are a whole bunch of other events that the browser knows about.

So change is a pretty useful one. And then we can pass in a function. So now let's create a function that we can pass [LAUGH] in. So why don't I take all of this fun little code that we have here of getting the currentTheme, figuring out what the newTheme should be, and then setting that as the new value of the data-theme attribute into a function which I could call, toggleTheme or changeTheme or whatever you wanna call it.

It's not gonna take any arguments because really all of the information this needs it's figuring out for itself. And now if I pass in the toggleTheme function to the addEventListener method on the toggle element, ideally, we have a working input element. Let's find out. My gosh, it worked.

Doesn't it feel good? Did anybody else have a different solution?
>> Someone just asked, why not use the arrow function?
>> Why not use the arrow function? Great question. In this case, we can totally do that. So maybe I don't actually need this toggle theme function for anywhere else except this one reference, right?

And I could also declare this, I could have declared this as toggleTheme equals and then an arrow function expression which looks like this, sometimes called a fat arrow. So we have the arguments and then this fat arrow and then the body of the function. So I could have declared it like that and then this would still work.

No reason not to. I like arrows. We all arrow people, arrow fans, arrowers or whatever. And in this case, I don't even really need to name this function and save it in a variable. Because I'm not gonna use it anywhere but this one place. So I could actually make this an anonymous function because it has no name, likes to stay incognito, That I declare where I need it.

So I could totally use an arrow function, or the function keyword even, to declare a, well actually, let me take that back. I could use an arrow function to declare a anonymous function that will work the same way, hopefully, indeed. So good question. In this case, there is no difference, yeah.

>> Someone had a solution where they just put ifthis.checked in the function and then doc.setAttribute data-theme equals dark or.
>> So we can also read attributes of the input object and we can check whether it is checked or not. We just have to make sure that we are also updating that every time the checked value changes which is pretty much the only thing in a checkbox that there is to change.

And that's why we want to be listening for that change event, so that we're not just basically setting it and forgetting it. We're allowing the user to have their way. So this was meant to be a quick, just review example to get us into the flow. And we are gonna be in our quick wins essentially working in the same pattern.

We're gonna have some very simple HTML, a script tag that is our job to fill out and hopefully we'll add some super-impressive functionality to the page. [LAUGH] Then what we're gonna be doing in part two of the course is pulling all that together into a more full featured web app.

So we're gonna be starting with bite sized pieces as we go through some of these language features and then we're going to pull them together into a, Bigger than bite sized piece into a meal sized piece. I don't know. We'll figure it out.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now