So now that we've seen how we can add an event listener to our HTML elements in order to listen for when
they get clicked, let's drill down and take a deeper look at how this addEventListener function works,
because it looks a little bit weird and different from the functions that we've seen so far.
So over here I've got the JavaScript Wikipedia page open, and I'm going to use it to show you a couple
of things,
and what happens when we add an event listener.
So one of the cool things that you can do in Chrome is you can highlight say the title here and you
can right-click, go into Inspect,
which brings up the Chrome Developer Tools, and you see that the element that's currently selected,
so the h1, can be accessed in the console using this $0 variable.
So if we head into the console and we type $0 and hit Enter, then you can see that this is bound
to the h1 element up at the top here. And you can do some cool things with this and mess around with websites.
Like if you say $0, which is the h1 element,
.innerHTML is equal to, instead of JavaScript,
let's say it's equal to AngelaScript.
And now I've just edited Wikipedia's website on the fly, and this is a fun way that you can mess with friends.
Now of course when you reload the website then all of your changes are gone because it's loading up
the html page from Wikipedia servers.
So all the changes that you're making is to your local copy of this Wikipedia page inside the browser.
But if you catch your friend unaware and edit some of these pages it's a pretty good prank.
Now at the moment when I click on this h1, absolutely nothing happens, because it's not a button and
it's not bound to any event listeners, at least not yet.
But that's exactly what we're going to do.
We're going to say $0, referring to the h1, .addEventListener, and the type of event that
we want it to listen to are clicks,
so that's the first input.
The second one is going to be a function and that function is simply going to console.log
the fact that I got clicked. All right. Cool.
So now if I hit Enter, then that click event listener gets added to our h1, and if I click on this I now
get the console log that says it got clicked. And I can do that many, many times.
Now, in this case we've got an anonymous function as the second input and we know that we can also specify
it like this.
So instead of using an anonymous function we could use a named function, say something called
respondToClick.
So the word click is the event that we're detecting and that's the first input or input 1.
Now the second input is the function that should be called once the h1 detects the click event.
So you can see that addEventListener is taking two inputs,
the first one specifying what event it should listen to, and the second one specifying what it should
do once that event gets detected.
Now, this is a little bit different from the functions that we've seen so far, because instead of just
passing in strings or numbers or other simple data types, we're actually passing in a function as an input.
Now because we can't look at the code that Chrome uses to implement addEventListener because we didn't
write that method,
so let's try and create both sides of the coin and in the process we can better understand how our event
listener works.
So let's say that we wanted to create a calculator.
So we could create a function that's called, calculator() and it could take two inputs,
the first number and the second number.
And then we're going to do some calculations with it.
So we'll say maybe return as the output the first number plus the second number.
So now if I call this function and I pass in some values, say 2 and 3, then I will get the output
as 5, right?
2 + 3.
Now if I wanted to change my calculator, so instead of adding my numbers I want my calculator to be able
to multiply,
then I would have to change my calculator function and say, instead of adding, actually I want my calculator
to take these two numbers, first number, second number, and then it should return the first number multiplied
by the second number.
So now I can call my calculator and pass in the same inputs, 2 and 3, and I'll get back 6, because now
our calculator function is multiplying the first number by the second number.
Now this is a little bit painful because, you know, the kind of calculators that we're used to allow us
to specify on the fly, whether we want to multiply, or add, or divide.
We don't actually have to go and change the actual calculator each time.
So what can we do instead?
Well, what if we created a function that was called add, and it took two inputs, the first number and the
second number?
And this function basically just adds the numbers, right?
So it returns the first number plus the second number. And then we go and create another function, and
we call this one multiply and this one again takes two inputs and it returns the first number multiplied
by the second number.
So now that we've got two different types of functions, how can we create a function that's called calculator
to be able to pick and choose whether we're going to add or multiply?
So this is a case where being able to pass in a function as an input to another function becomes really
handy.
So say we've created this function called calculator and instead of simply just taking two numbers as
the inputs, it's also going to take an input called the operator, and this input can be changed on
the fly when we're calling this function.
And when this function calculator gets called, we simply call the operator function, whatever it is that
the user chose, passing in the two inputs and return that value as the output.
All right. So now let's go and hit Enter and have all three of these functions available to us,
and let me show you how we would call this.
So instead of having to say add 2 and 3, or multiply 2 and 3, we can simply call our calculator
function, and we can pass in our numbers, let's say 4 and 5,
and the third input, as you can see here, is expecting a function, because it's going to call it inside
the body of this calculator.
So let's say if we wanted to use our calculator to add 4 to 5, then we can simply specify the name
of our add function that's created up here,
and if we hit Enter you'll see that we get the result 9.
Now if we decided to use the multiply function instead, then what would happen is that we would call
the calculator function, it would go and find where it was declared, 4 would get passed into the first
input, num1, 5 becomes num2, and multiply becomes operator.
So once it gets into the body of the function, it's going to output whichever function was passed in
as the operator,
so in this case multiply, and it will pass into that function multiply the same two numbers that we passed in
to calculator.
So now if I hit Enter you can see we get 20 because our calculator is using this function to calculate,
instead of this one.
Now before we mentioned that Chrome Developer Tools does a whole bunch of really awesome things, and one
of those things is something called the debugger.
So if you just type in the keyword debugger and then hold down shift and hit Enter, then call the function
that you want to debug,
say calculator, I don't know, 3 and 4, and multiply,
and then we hit Enter, then we enter the debug mode.
So this is cool.
And what you can do here is you can step through all of the steps that the browser goes through to give
you that final answer.
So we can see the process step by step.
So this is usually used when you're trying to figure out what's going wrong in your code, because instead
of playing computer in your head when you're imagining what should happen every step of the way, sometimes
you're wrong and it's really useful to see what's actually happening every single step of the way.
So let's stop.
The first thing to do is you're going to click on this button here with a down arrow, and this steps into
the next function call.
So once I click on it we start off by calling the function calculator.
So it goes and finds where that function was defined which is here of course, and it passes in those
inputs that we gave before which is 3, 4 and multiply.
So now num1 = 3,
num2 = 4,
and the third input, operator, is equal to a function, as denoted by the little f sign and the function
is the multiply function which is up here.
So now the next step is that it enters into the body of the calculator function and it tries to call
this function operator which is currently the same as the multiply function.
So now, if we keep stepping through, it finds that multiply function and it subs in those two inputs,
where num1 is equal to 3,
and num2 is equal to 4,
and it returns the value of num1 multiplied by num2.
So now if we continue stepping through it takes that value that we got back and returns it as the output
of the multiply function and then returns it as the output of the calculator function.
And finally we get to the end of our code and we output the number 12.
So this is a pretty neat trick
whenever you're getting confused what's actually happening in each of the functions you write.
And this way you can see stepwise, everything that the browser is doing;
one function call at a time.
These types of functions which can take other functions as inputs are called Higher Order Functions
and this feature is available in a number of modern languages like JavaScript, Pascal, Swift, and a whole
bunch of other ones,
but it's not universal.
It's not something that's available in all programming languages, but it's something that we'll rely on
heavily in JavaScript as we learn to manipulate the DOM and give our website more and more behavior.
So we'll come across this many many times. Now, as a challenge,
I want you to create a full set of operators for our calculator.
So I want you to create the code that we've already made,
so a calculator that takes two inputs and a function as an input, and complete these functions so that
we have an add function,
we have a multiply,
we have a divide and a subtract so that when you call the calculator you can say something like, "Calculator
6 and 3 and subtract," and it will give you the right answer.
So pause the video and complete that challenge, and once you're done go ahead and try out the debugger and
step through the function calls so that you're happy with how it works and how you can pass functions
as inputs to other functions.