Instructor: Before we move on,
with coding the roll the dice button,
let's talk about another important topic
that is closely related with the DOM and DOM manipulation,
and its events.
events are like notifications
that are sent to notify our code
that something happened on the webpage.
And events are triggered by things like clicking a button,
resizing a window, scrolling down, or, even pressing a key.
We can use Event Listeners to code responses
to all these events, like, opening up a pop-up window,
showing animations, and so on, and so forth.
So, an Event Listener is just a function
that basically sits there and waits
for a specific event to happen.
And how is that event then processed?
Well, first, we need to remember about the Execution Stack.
And that's because, the rule is that an event
can only be processed, or handled,
as soon as the Execution Stack is empty.
Which means, all of the functions have returned.
So, in here, we currently have two Execution Contexts
on the Stack.
So, these have to return first.
Just like this.
Okay, so besides the Execution Stack,
we also have something called the Message Queue
in the JavaScript engine.
This is where all the events
that happen in the browser are put.
And they sit there, waiting to be processed.
Which, as I said, only happens once the Execution Stack
is empty.
And that is the case now, here, in our example.
So, the next event in the line, will now get processed.
Remember, from the last slide,
that we can have something called an Event Listener,
which is a function that reacts to an event.
So, that Event Listener is now called.
And since it's a function,
it gets its own Execution Context,
which is then put at the top of the stack,
and becomes the active Execution Context.
So, this is how event are processed,
and how Event Listeners work.
So, let's now use what we just learned in practice,
in the rest of the lecture.
In this lecture, you will learn how to
set up an event handler, what a callback function is,
and also, what an anonymous function is.
You'll also learn another way to select elements by IDs,
and, how to change the image in the HTML image element.
Alright, so let's now set up our event handler.
And the first step is to select the element
in which the event will happen.
So in this case, it will be the button,
where we will roll the dice.
So, this button here, right?
So, let's go into our HTML file,
and find out how this one is called.
And it's this one here, so, roll dice,
and the class for this one is the button roll.
Button, right?
So, B-T-N roll.
Okay.
Once again, we need to select this element.
So, by now, you've seen that it always works like this.
So, we first select something, using querySelector.
So, like this.
Then after that, we do something with that selection
that the querySelector method returns.
So, once again, we use document.querySelector.
And now, we use the button roll.
Alright.
So we have our selection, and now,
we can add the Event Listener, which is as simple as this,
add, and here, we already have it.
So, addEventListener.
And here, we have two arguments.
The first one is the event type, which in our case,
is simply click.
So there are a lot of events, as I told you,
and this one is the click event,
but there are a lot of them.
And so, we have a nice, handy reference,
which I already have here.
So, once again, this is on the MDN webpage,
where I also showed you the operator precedence table.
So, let's search for the one that we used.
So, click.
So, this is the click event.
And it's one of the Mouse Events.
But there are lots of them, so, mouseenter, mousemove,
mouseover, mousedown, mouseup, and all of these events.
Then, we have Drag & Drop Events.
We have these Media Events.
And, we also have Keyboard Events up here,
Clipboard Events, so when we copy or cut something,
and let's just see lots of events are possible.
For example, when the page unloads, or when our page loads,
and all these kinds of Events.
So when you need something else, beside click,
or beside anything that we will learn in this course,
you can just come to this reference here,
and use it from there.
Okay, so the first argument to the addEventListener,
is the type of event.
Now, the second part is the function that will be called
as soon as the event happens.
So, for now, we'll leave this empty.
So, imagine that we would have a function
that we want to call, when we click on the button.
So, I'm just going to call it function button,
with no parameters and just like this.
Do something here.
Okay.
So, remember, if you wanted to call this function,
we would do it like this, button, and then
the call function operator, which is this one, right?
So, in order to call a function,
we always use these parentheses.
Now, if you want to use this function,
as our function, that is called here,
as soon as we click in on the button,
then, we would simply do it like this,
just the name of the function,
without the parenthesis operator,
because we don't want to call it right here.
We want the Event Listener to call the function for us.
And this button function
is then called the callback function.
And that's because it's a function that is not called by us,
but, by another function.
So, this is what a callback function is.
The function that we pass into another function,
as an argument, and this function, in this case,
the EventListener method,
will then call that function for us.
Alright.
But, what if we didn't want to have an external function
that gets called by the Event Listener?
We could simply add the function right here, so,
instead of having this function name here,
we could write our function right here.
And that would be an anonymous function.
So, another concept here.
So, an anonymous function is simply a function
that doesn't have a name.
So, it cannot be reused.
We can just write function here, like this,
then the usual way with our brackets, open it,
and then write our function code right here,
such as we did before.
So, once again, we can write Do something here.
Again, if we don't want this function here,
on the outside, we can very simple write our function
right here, into this EventListener method.
And we do that by writing an anonymous function,
which is a function that doesn't have a name,
and that we, therefore, cannot use outside
of this context here.
So we cannot call this function button
to use it then later, in another place.
So, this function can then only be used here.
But in this case, that's what we want,
because, we don't want to use the button function
anywhere else.
All we need this to happen, is when someone clicks
on a button.
So, an anonymous function is the perfect solution here,
in this case.
And this usually the way that we handle this.
Now, what happens as soon as someone clicks the button?
So, let's use comments here to define our next steps
that we have to take here.
So first, we need a random number.
Right, and we already did that.
So, let's already copy this here into our function.
So, we only need this number, as soon as
someone hits the button, right?
We don't need this right after our application loads.
We only need this as soon as someone clicks.
Okay.
And after that, what we need then, is to display the result.
Right?
And after that, what we want to do then,
is to update the round score,
but only if the rolled number was not a one.
Because, remember, if we roll a one, then we lose,
or, a current score, and it's the next player's turn.
Alright.
So, here, our dice variable.
I will actually, only declared a variable here,
in this function, because I don't need it from the outside.
So, remember, due to the scoping chain,
here, in the outside scope, we will only have access
to the variables that are in this scope,
and not access to the variables that are in the scope
of another function.
So, I will remove it from here.
And now, this function is the only one that has access
to the dice variable.
But, the other way around, from this function here,
we have access to the other scope, right?
So, in this function, we will have access to the scores,
the roundScore, and activePlayer variables.
And this is very important.
So, once again, the scoping chain
is something very important,
and really important, also, to understand.
Okay, so we have our random number.
Now, we also need to display
the correct dice number, right?
So, we first have to make it visible again,
because we hid it up here.
So, we set the display style to none.
So, the first thing is to bring the style back to block.
So, in CSS, when we want to display something as a block,
we simply use the display property, instead of to block.
So, document.querySelector...
And we see from up there, that it's just the class dice,
and then dot style, and dot display...
And set it to block.
Alright, but we also need to set the correct number, right?
And this is why these images, so, one, two, three,
four, five, six, have the number here in their name.
So, this is a trick that I used,
so that now, it's very simple for us
to display the correct name.
All we need is to write this name,
and then add the number of the dice value
that was wrote, right?
So, if we roll a one, then we need the dice-1 image,
and the same thing for the other numbers.
So, how do we do that?
Once again, we will select our dice.
But, instead of always doing the same selection
over and over again, which is a process
that takes up some time, so it's not perfect if we do
all the same operation all the time.
So, what I can do instead, is to create a variable,
where I store the selection, and then,
use this variable whenever I need it.
So, I will create a new variable, and once again,
we only need it in this scope, and not in the outside.
So, I only declare it here, in this function.
Then, we'll call it diceDOM, simply because it's
the DOM object for this dice.
And so, now I'm going to copy this part,
because this is effectively, or selection, right?
So, querySelector off the dice, is what we select.
And now, all we have to do, is to use the variable of that
we just created, so we can make it like this.
And now, down here, we can use it again.
And we don't have to make the selection over and over again.
Now, how do we change the image of an image element?
So we see here, that the image is an img element,
and a source is what defines which image is displayed.
So, it's very simple to change this source attribute,
because in JavaScript, all we have to do,
is exactly that, source.
S-R-C.
And so, now we use this trick that I told you about.
We just write this part of the name.
So, dice, and then, the number that was wrote.
So, dice, plus, so actually, dice.
Right?
Because, this variable here, which has the number,
from one to six, which the dice rolls.
And now, we just have to add the final .png.
Plus, .png.
And that's it.
So, it's now time to test this again.
So, let's reload this, and then roll the dice.
And now, it's not really working.
So, let's check out the console and the error that we get
is that the dice is not defined in line 20.
So, let's check that one out, and yes, indeed.
So, here, we used the dice, but it's not defined,
because it's only defined on here.
But, it's not a problem, because these lines here,
in the beginning, they were only to show you some things,
which I don't want anymore here, anyway,
because, we are just going to use these
inside of a function, or even off another function.
So this one, were just to test some things.
So, I will just cut them here, and put them down here,
in case I need them later.
And I will need them, of course.
So, the only thing that matters,
for application here, really, is these variables,
then hide the dice, and then,
or, EventListner function here.
So, let me close this.
Reload.
And now, it's going to work.
Alright.
So, five, six, six, three, and so on.
So now, this works.
Really cool, right?
So, our game is starting to look nice, right?
What I want to do now,
is to actually set these values here to zero.
And I'm not going to do that in the HTML code,
but right in the JavaScript.
So, let's do that.
So, we come here, to our HTML, to see how these are called.
And these are the score-0, current-0,
and score-1 and current-1 IDs.
And then, so, these are IDs.
Now, we could, of course, use the document.querySelector
just fine, such as we did before,
but I want to show you another method now,
which is to document .getElementByID,
instead of querySelector.
So, this only works for IDs,
but is faster than querySelector.
So, sometimes, when we have IDs,
instead of just using querySelector all the time,
that we use getElementByID, for IDs.
So, let's do that.
So, document.getElementByID.
And now, we don't use the CSS style.
So, we don't use the hash symbol, such as we did,
if we would use the querySelector.
But all we do, is to put the name in here.
So, it's score-0, and then textContent,
as you already know, right?
And set it to the string of zero.
And I will now duplicate this line.
And we'll do the same for the score, one.
And I will actually duplicate it two more times,
so we do it for the current, current-0,
and then, current-1.
Okay, and with this, we set all the four values to zero.
So, again, we could've used querySelector here,
but we used the getElementByID method,
which is a bit faster.
And also, because, I wanna show you that querySelector
is not the only way that we have to select elements.
So, let's now check this out.
And, indeed, everything is now set to zero.
Alright.
Are you excited to continue with this?
Then come with me, right to the next lecture.