In this example, I'm assuming that the webpage is a calculator, similar to:
|---------------|
| |
|---------------|
| 1 | 2 | 3 | * |
|---|---|---|---|
| 4 | 5 | 6 | / |
|---|---|---|---|
| 7 | 8 | 9 | = |
|---------------|
In this case, the button buttons[i]
is one of the calculator buttons; | 1 |
, | 5 |
, etc. The actual number of the button is its index, so buttons[2]
would be | 2 |
, buttons[7]
would be | 7 |
, etc. And I'm guessing other values, like buttons[0]
and buttons[10]
, are the operator buttons (| = |
, | * |
, | / |
).
Now, when the user clicks on one of these buttons, the character on the button, which is the button's innerHtml
, is added to the calculator's result
(by adding it to the result's innerHTML
), which is just a display of the operation. So if I clicked | 3 |
, then | * |
, then | 5 |
, the calculator would look like
|---------------|
| 3*5 |
|---------------|
| 1 | 2 | 3 | * |
|---|---|---|---|
| 4 | 5 | 6 | / |
|---|---|---|---|
| 7 | 8 | 9 | = |
|---------------|
Here's where the addEventListener
comes into play. When you call element.addEventListener("click", func)
, whenever element
is clicked, func
will be called. So to add the button to the result when it's clicked, you could do:
buttons[i].addEventListener("click", addButtonValueToResult);
where addButtonValueToResult
is the function to add the button's value to the result.
The problem is, the different buttons have different values, so one function like this won't work for all of them. Therefore, addButtonValueToResult
can't be a simple function; each button needs its own function. One such solution is to ditch the for loop and just do something like:
buttons[1].addEventListener("click", add1ToResult);
buttons[2].addEventListener("click", add2ToResult);
buttons[1].addEventListener("click", add3ToResult);
...
and then have functions like:
function add1ToResult() {
result.innerHTML += "1"
}
But this takes a lot of unneeded work, because you need to add functions for each of the number buttons (| 1 |
through | 9 |
) as well as the operator buttons (| = |
, | / |
, and | * |
), which just add their innerHtml
s to the result. Moreover, the button's index is already assigned to a variable i
and the entire button can be referenced with that index with buttons[i]
. Couldn't you just have the program make a function automatically, for each button, that when given the button's index i
, gets the button (through buttons[i]
) and adds that button's value to the result?
Well that's exactly what this program does: addValue(i)
doesn't just add the button's inner value itself; it returns another function that, also with a few test cases for special buttons, adds the button's inner value. Looking at this code:
function addValue(i) {
return function() {
if(buttons[i].innerHTML === "÷") {
result.innerHTML += "/";
} else if (buttons[i] === "x") {
result.innerHTML += "*";
} else {
result.innerHTML += buttons[i].innerHTML;
}
}
};
Say you call addValue(3)
; this will return a function that will add the digit 3
to the result, in result
. If you call addValue(9)
; this will return a function that will add the digit 9
to the result, in result
. You can call the function addValue
returns and actually add a digit to the result, through (addValue(digit)()
). But addEventListener
doesn't take an evaluated result; it takes a function, which it will later call when the button is clicked.