Callback functions and automatic passing of input parameters
There are two ways a function can get called in Javascript:
- Calling a function by ourselves manually
- The Javascript engine calls the function for us automatically as part of event handling or processing an array.
1) Calling a function by ourselves manually
We already know how this works.
We called the alert()
function by ourselves manually:
alert("Hurray! 50% Off!");
We called the addTwoNumbers
function by ourselves manually:
function addTwoNumbers(firstNumber, secondNumber){
const result = firstNumber + secondNumber;
console.log(result);
}
addTwoNumbers(5, 10); //Outputs 15
2) The Javascript engine calls the function for us automatically as part of event handling
We already know how this works, too.
For example, when a button is clicked, the Javascript engine calls the showModal
function (event handler) automatically to reveal the modal:
function showModal(){
let discountModal = document.querySelector("#surprise-discount-modal");
discountModal.style.display = "block";
}
let showModalButton = document.querySelector(".show-modal-btn");
showModalButton.addEventListener("click", showModal);
Similarly, when the menu icon is clicked, the Javascript engine calls the anonymous function to reveal the off-canvas menu:
menuToggleButton.addEventListener("click", function(){
document.body.classList.toggle("off-canvas-is-open");
});
In both cases, we do not call the event handler functions by ourselves. We can't do that.
The Javascript engine is responsible for waiting for events to occur and then calling the appropriate functions to perform the task.
If a Javascript engine calls a function for us automatically, we call that function a callback function.
As simple as that.
But why use the term "callback"?
At least once in your lifetime, you might have told someone, "I will call you back later!"
This means you will call them back at a later point in time, right?
The "callback" functions in Javascript work similarly.
Apart from exceptions related to processing arrays, a callback function is never executed immediately after the Javascript engine sees it.
function showModal(){
let discountModal = document.querySelector("#surprise-discount-modal");
discountModal.style.display = "block";
}
let showModalButton = document.querySelector(".show-modal-btn");
showModalButton.addEventListener("click", showModal);
For example, in the above snippet, the showModal
function is not executed immediately.
The Javascript engine will call the showModal
function at a later point in time when a user clicks the button.
Hence the term "callback function".
Anyway, now that you understand callback functions, a new question has popped into my head.
When we are calling a function manually by ourselves, we are capable of passing input parameters to them as arguments:
alert("Hurray! 50% Off!");
In the above code, while calling the alert()
, we are passing a message as an argument.
function addTwoNumbers(firstNumber, secondNumber){
const result = firstNumber + secondNumber;
console.log(result);
}
addTwoNumbers(5, 10);
Similarly, in the above code, we are passing the values 5
and 10
when calling the addTwoNumbers
function.
We have the control to pass inputs if the function we are calling supports them or needs them.
In a similar way, when a Javascript engine calls a function as part of event handling, is it capable of passing inputs to that function?
For example, the Javascript engine is calling our showModal
function automatically when the button is clicked:
function showModal(){
let discountModal = document.querySelector("#surprise-discount-modal");
discountModal.style.display = "block";
}
let showModalButton = document.querySelector(".show-modal-btn");
showModalButton.addEventListener("click", showModal);
So, can the Javascript engine pass any inputs when it calls our showModal
function?
The answer is yes.
In fact, every time an event occurs, the Javascript engine calls the associated event handler function by internally passing an event
object as an argument to it.
showModal(event);
//This happens internally. We can't see this function call.
Be it a named event handler or an anonymous one, the Javascript engine calls our callback functions by passing them an event
object.
We don't know this because accepting the event
object as an input parameter is totally optional, and we ignored it because it was not useful during our previous exercises.
But if we are interested in them inside our callback functions, we just have to make the "event" parameter part of our callback function definition to make use of it as part of the event-handling process.
Here is an example of using the "event" parameter as part of our showModal
function definition:
function showModal(event){
let discountModal = document.querySelector("#surprise-discount-modal");
discountModal.style.display = "block";
}
let showModalButton = document.querySelector(".show-modal-btn");
showModalButton.addEventListener("click", showModal);
Now, we can use the event parameter inside the function body like this:
function showModal(event){
console.log(event);
...
}
let showModalButton = document.querySelector(".show-modal-btn");
showModalButton.addEventListener("click", showModal);
We can do the same with anonymous callback functions, too:
menuToggleButton.addEventListener("click", function(event){
console.log(event);
document.body.classList.toggle("off-canvas-is-open");
});
This way, when the Javascript engine calls our callback function and passes the event
object as an argument to it, and we can capture it and use it inside our callback function's body.
The event object becomes useful while working on tasks such as:
- Disabling the right-click on a web page
- Image Gallery
- Overriding the default behavior of keyboard shorts
- The list goes on and on
This is because the event
object contains a lot more information, such as:
- On which target HTML element is the event generated? We can use the
target
property on theevent
object to answer this question:
event.target;
- Where exactly has the user clicked? We can the
clientX
andclientY
properties to answer this question:
event.clientX; //Gets the horizontal coordinates
event.clientY; //Gets the vertical coordinates
On top of that, the event
object also has methods to change the behavior of the event that occurred.
For example, there is a method called preventDefault()
on the event
object that will be extremely helpful to us during the "Disable Right Click" project.
But before working on that project, we need to talk about something important: naming the input parameters, and we will do that in the next lesson.