JavaScript's Unsung Hero: How to .addEventListener()
Tags: javascript, beginners, tutorial, html
Published: 2023-01-15 01:26:06

If you're anything like me, you like to see the big picture. Understanding *how* things fit together makes them easier to learn. When I first started learning JavaScript, I wanted to know how vague concepts translated into usable code. One of the biggest connections I made early on was understanding the relationships between HTML, CSS and JS.

When it comes to websites, HTML provides content, CSS provides styling, and JS provides functionality. These three elements work together to create powerful webpages and applications. Of all the methods that are available in the JS engine, `.addEventListener()` is the unsung hero.

##The Unsung Hero
JavaScript's `.addEventListener()` method is the unsung hero because this simple, easy-to-use method connects the power of the JS engine to the DOM. An event listener attaches to any HTML or DOM element—even the window—and enables JS to respond to the associated events that it "hears." In other words, the ability for JS to "hear" when an HTML `<button>` is `'clicked'` comes from the event listener. 

While an event listener can only listen for one event, multiple listeners can be added to a single element. For instance, a mouse hover and click can be added to the same button with different functions dependent on the action.

##What is the .addEventListener() method?
The `.addEventListener()` method has two required parameters and one optional parameter. Parameter one is the `event`. Parameter two is a `function`. Parameter three is an optional `boolean` with a default set to false. This determines whether the event listener will use event bubbling(true) or event capturing(false). So the basic syntax would be:

```javascript
element.addEventListener('event', function);
```
Or
```javascript
element.addEventListener('event', function, true);
```

##Parameter 1: 'event'
The first parameter is an event. You can find an entire list of HTML DOM events [here](https://www.w3schools.com/jsref/dom_obj_event.asp). The three events I'll cover in this post are `'click'`, `'submit'` and `'DOMContentLoaded'`.

###'click'
The mouse `'click'` is the primary event that most websites use. Let's attach the `'click'` event listener to the buttons in this HTML example:
```html
<div>
    <button id="like">👍</button>
    <button id="dislike">👎</button>
</div>
```
```javascript
document.querySelector('#like').addEventListener('click', likeHandler);
document.querySelector('#dislike').addEventListener('click', likeHandler);
```
As an aside, if you have a situation like this where the same handler function is being called on more than one button, use `querySelectorAll` and iterate over both buttons like this:
```javascript
document.querySelectorAll('button').forEach((button) => button.addEventListener('click', likeHandler));
``` 
###'submit'
The submit event listener attaches directly to a form not the specific:
`<input type="submit" value="Submit">`.
Even though the `type="submit"` looks like a button and is clicked like a button, the event that JS listens for is `'submit'`.

```javascript
document.querySelector('form').addEventListener('submit', formHandler);
```

###'DOMContentLoaded'
Another powerful way to use the `.addEventListener()` method is with the `DOMContentLoaded` event. When the browser reads the HTML document, it loads the JS file on the line where it is written. If the JS file is scripted in the `<head>` of the page, none of the other content will be loaded before the script is run. This becomes a problem when the script tries to access elements from the DOM that have not been created yet. 

One solution to this problem is achieved by placing the script after the element that it modifies. However, using `DOMContentLoaded`, is an elegant solution that does not compromise the organizational layout of the HTML document.

```javascript
document.addEventListener('DOMContentLoaded', init);

function init() {
    // Code block to initialize website.;
}
```
The event listener is added to the entire document. Once the document has fully loaded, the event listener triggers the `init()` function. 

##Parameter 2: function
The second parameter is a function. Typically when a function is called, it is also invoked. However, as a parameter in this method, we don't want the function invoked when we call it. Rather we want to invoke the function after the event has occurred. 
```javascript
function myFunction() {
    console.log('This is a delayed response!');
}

button.addEventListener('click', myFunction);
```
Notice the missing `()` when the function is called. The event listener only invokes the function once the button is clicked.
```javascript
function myFunction() {
    console.log('This is NOT a delayed response!');
}

button.addEventListener('click', myFunction());
```
Since the function is invoked when it is called, myFunction will run immediately instead of waiting for the `'click'` event.

##Passing parameters
So how can parameters be passed to functions that have no parentheses? In this case, create a trojan horse and place the function with parameters inside of an anonymous function.
```javascript
function addSumNums(num1, num2){
    return num1 + num2;
}

button.addEventListener('click', function(){
    addSumNums(num1, num2);
}
```
##Parameter 3: boolean
The boolean value of parameter 3 is set to a default of false. That is why it is an optional parameter. What does this parameter address? It addresses the order in which events are handled with nested tags. 
```html
<div>
  <p>Some text that is both meaningful and important.</p>
</div>
```
With the default setting, the outer-most event will be handled first. This is called event capturing.
```javascript
div.addEventListener('click', myFunction) // This one's first!
p.addEventListener('click', myFunction)
```
With a boolean of true, the inner-most event will be handled first. This is called event bubbling.
```javascript
div.addEventListener('click', myFunction, true)
p.addEventListener('click', myFunction, true) // This one's first!
```
##Conclusion
So that's it! The `.addEventListener()` method is the unsung hero of JavaScript because it connects any and every function to any and every element in the DOM. It is easy to use and only requires two parameters. 
######Credit
Photo by <a href="https://unsplash.com/@benwhitephotography?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Ben White</a> on <a href="https://unsplash.com/s/photos/hero?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>