Understanding JavaScript Events
Tags: javascript, webdev, programming, productivity
Published: 2022-09-10 14:21:32

The interaction of JavaScript with HTML is handled through events. Events are actions that occur when either the user or the browser itself manipulates the page.

Some common events that occur with websites are page loads, button clicks, keypresses, hovers, form submissions, window resizing, to name but a few.

As developers, we can use these events to execute coded responses, such as displaying messages, validating data, reacting to button clicks, and really anything else we can imagine!

## What are Event Handlers & Event Listeners?
An event is fired whenever an action occurs on a page that JavaScript can react to, such as when a user clicks on a button (click event) or presses a key (keypress event).

An event handler is a JavaScript function that runs when an event fires.

An event listener attaches responsiveness to a given element, which allows the element to wait or “listen” for the given event to fire.

Events can be assigned to elements via inline event handlers, event handler properties & event listeners. Let’s take a look at each of these methods.

## Inline Event Handlers
Let’s start with a basic example of an inline event handler. The below HTML consists of a `button` and a `p` element, we want the text content of `p` to change when the user clicks the `button`.
```html
<!DOCTYPE html>
<html lang="en-US">

<head>
    <title>Understanding Javascript Events</title>
</head>

<body>

<button onclick="changeText()">Click me</button>

<p>Change me!</p>

</body>
</html>
```
As you can see, we’ve added an attribute called `onclick` to our `button` element. The attribute value will be a JavaScript function we’ll create called `changeText()`.

Now let’s create our function! I’ll add it between script tags for this example:
```js
<script>

// Function to modify the text content of the paragraph
const changeText = () => {
    const p = document.querySelector('p');

p.textContent = "I was changed with an inline event handler!";
}

</script>
```
Our `changeText()` function modifies the `textContent` of our `p` element.

So now when you click on the button, the event fires which runs our changeText()function, which alters the text in our p tag.

While inline event handlers clearly work — they really shouldn’t be used in production. For the same reason that inline CSS shouldn’t be used, it’s messy! And our code will be much more maintainable, if we handle our JavaScript entirely in separate script files, rather then having handlers throughout our HTML.

## Event Handler Properties
Event handler properties work very similarly to inline handlers, except we set the property of an element in JavaScript, instead of on the attribute in our HTML.

Our HTML is the same, except we’re now excluding the `onclick="changeText()"` we used previously:
```html
<!DOCTYPE html>
<html lang="en-US">

<head>
    <title>Understanding JavaScript Events</title>
</head>

<body>

<button>Click me</button>

<p>Change me!</p>

</body>
</html>
```
And our function will remain similar as well, except now we need to access the `button` element in our JavaScript. We simply access `onclick` just as we would access `style` or `id` or any other element property, then assign the function reference.
```js
// Function to modify the text content of the paragraph

const changeText = () => {
  const p = document.querySelector('p');
  p.textContent = "I was changed with an event handler property!";
}

// Add event handler as a property of the button element

const button = document.querySelector('button');
button.onclick = changeText;
```
_Note_: Event handlers do not follow the camelCase convention. Notice the code is `onclick`, not `onClick`!

Now when you click the button, it’ll fire the event from our JavaScript property.

You’ll see that when passing a function reference to the `onclick` property, we don’t include parentheses, as we are not invoking the function at that moment, but only passing a reference to it.

The event handler property is more maintainable than the inline handler, but it still isn’t the greatest way to manage events. If for example, you tried to set multiple `onclick` properties, all but the last one would be overwritten, as demonstrated below:
```js
const p = document.querySelector('p');
const button = document.querySelector('button');

const changeText = () => {
    p.textContent = "Will I change?";
}

const alertText = () => {
    alert('Will I alert?');
}

// Events can be overwritten!

button.onclick = changeText;
button.onclick = alertText;
```
In the above example, the `button` click would **only** display an alert, and not change the `p` text, since the `alert()` code was the last one added to the property.

Now that we have an understanding of both inline event handlers and event handler properties, let’s move onto event listeners.

## Event Listeners
Event listeners watch for an event on an element, instead of assigning the event directly to a property on the element, we’ll use the `addEventListener()` method to listen for the event.

`addEventListener()` takes two mandatory parameters — the event to listen for and the listener callback function.

The HTML for our event listener will remain the same as the previous example. And we’ll still be using the same `changeText()` function as before.

However, we'll now attach the `addEventListener()` method to the button, as follows:
```js
// Function to modify the text content of the paragraph

const changeText = () => {
    const p = document.querySelector('p');
    p.textContent = "I changed because of an event listener.";
}

// Listen for click event

const button = document.querySelector('button');
button.addEventListener('click', changeText);
```
_Note_: In the first two methods, a click event was referred to as `onclick`, but with event listeners, it is referred to as `click`. Every event listener drops the `on` from the word.

Event listeners appear very similar to event handler properties, however, they have a crucial advantage. We can set multiple event listeners on the same element, for example:
```js
const p = document.querySelector('p');
const button = document.querySelector('button');

const changeText = () => {
    p.textContent = "Will I change?";
}

const alertText = () => {
    alert('Will I alert?');
}

// Multiple listeners can be added to the same event and element

button.addEventListener('click', changeText);
button.addEventListener('click', alertText);
```
We can see how both events have fired, providing the user with both an alert and modified text once clicking out of the alert.

It’s more concise to use anonymous functions instead of function references on event listeners. Anonymous functions are functions that are not named, such as:
```js
// An anonymous function on an event listener

button.addEventListener('click', () => {
    p.textContent = "Will I change?";
});
```
We could also use the `removeEventListener()` function to remove one or all events from an element.
```js
// Remove alert function from button element

button.removeEventListener('click', alertText);
```
It’s also useful to know that you can use `addEventListener() on the `document` and `window` object.

Event listeners are currently the most common and preferred way to handle events in JavaScript. Next up we’ll take a brief look at some of the more common events that we’re likely to work with.

## Common Events
So far we’ve focused on using the click event while learning about inline event handlers, event handler properties and event listeners. However there are many more events available for us to work with, so let’s take a look!

### Mouse Events
Mouse events are among the most frequently used events. They refer to events that involve clicking the mouse button or hovering and moving the pointer. And of course, these events also correspond to the equivalent action on a touch device. Some examples are:

- `click` Fires when the mouse is pressed and released on an element.
- `dblclick` Fires when an element is clicked twice.
- `mouseenter` Fires when a pointer enters an element.
- `mouseleave` Fires when a pointer leaves an element.
- `mousemove` Fires every time a pointer moves inside an element.

A `click` is actually a compound event that is comprised of combined `mousedown` and `mouseup` events, these fire when the mouse button is pressed down or lifted, respectively.

Using `mouseenter` and `mouseleave` together recreates a hover effect that lasts as long as a mouse pointer is on the element.

### Form Events
Form events are actions that relate to forms, such as `input` elements and whether they are selected or unselected, and also form submission.

- `submit` Fires when a form is submitted.
- `focus` Fires when an element (such as an input) receives focus.
- `blur` Fires when an element loses focus.

Focus is achieved when an element is selected, for example, through a mouse click or navigating to it via the `TAB` key.

JavaScript is often used to submit forms and send the values through to a back-end language. The advantage of using JavaScript to send forms is that it does not require a page reload to submit the form, and JavaScript can be used for form validation.

### Keyboard Events
Keyboard events are used for handling keyboard actions, such as pressing a key, lifting a key, and holding down a key.

- `keydown` Fires once when a key is pressed.
- `keyup` Fires once when a key is released.
- `keypress` Fires continuously while a key is pressed.

Although they look similar, `keydown` and `keypress` events do not access all the exact same keys. While `keydown` will acknowledge every key that is pressed, `keypress` will omit keys that do not produce a character, such as `SHIFT`, `ALT`, or `DELETE`.

Keyboard events also have specific properties for accessing individual keys.

If a parameter, known as an `event` object is passed through to the event listener, we can access more information about the action that took place. Three properties that pertain to keyboard objects include `keyCode`, `key`, and `code`.

For example, if the user presses the letter `a` key on their keyboard, the following properties pertaining to that key will surface:

- `keyCode` A number pertaining to the key e.g. “65”
- `key` Represents the character name e.g. “a”
- `code` Represents the physical key being pressed e.g. “KeyA”

Let’s take a closer look at this with the following code:
```
// Test the keyCode, key, and code properties

document.addEventListener('keydown', event => {
    console.log('key: ' + event.keyCode);
    console.log('key: ' + event.key);
    console.log('code: ' + event.code);
});
```
You could save this code inside of script tags in a new HTML file. Then open up your browser, go to developer tools and open up the console tab. You’ll then see the information is logged every time you press a key on the keyboard. For example, if you press the ‘a’ key, your output would be:
```
keyCode: 65
key: a
code: KeyA
```
The `keyCode` property is a number that pertains to the key that has been pressed. The `key` property is the name of the character, which can change — for example, pressing `a` with `SHIFT` would result in a `key` of `A`. The `code` property represents the physical key on the keyboard.

Note: the `keyCode` property is being deprecated so it’s preferable to use `code` in new projects.

Check out the complete list of events [here](https://developer.mozilla.org/en-US/docs/Web/Events).

## Event Objects
The `Event` object consists of properties and methods that all events can access. In addition to the generic `Event` object, each type of event has its own extensions, such as `KeyboardEvent` and `MouseEvent`.

The `Event` object is passed through a listener function as a parameter. It is typically written as `event` or `e`. We can access the `code` property of the `keydown` event to replicate the keyboard controls of a PC game.

Let’s test it out with the following HTML:
```
<!DOCTYPE html>
<html lang="en-US">
<head>
    <title>Event Objects</title>
</head>
<body>
   <p></p>
</body>
</html>
```
Open it up in your browser, and paste the following code into your developer console:
```
// Pass an event through to a listener

document.addEventListener('keydown', event => {
    var element = document.querySelector('p');

    // Set variables for keydown codes
    var a = 'KeyA';
    var s = 'KeyS';
    var d = 'KeyD';
    var w = 'KeyW';

    // Set a direction for each code
    switch (event.code) {
        case a:
            element.textContent = 'Left';
            break;
        case s:
            element.textContent = 'Down';
            break;
        case d:
            element.textContent = 'Right';
            break;
        case w:
            element.textContent = 'Up';
            break;
    }
});
```
When you press one of the keys `a`, `s`, `d`, or `w`, you'll see an output.

I’m sure you’re now seeing that by having this control over how the browser responds — we can build increasingly dynamic websites.

### Event.Target
In this final section, we’ll look at one of the most frequently used event properties: the `target` property.

Let’s work with the following HTML:
```
<!DOCTYPE html>
<html lang="en-US">
<head>
    <title>Target</title>
</head>
<body>
  <section>
    <div id="one">One</div>
    <div id="two">Two</div>
    <div id="three">Three</div>
  </section>
</body>
</html>
```
Using `event.target` within our browser's Developer Console, we can place one event listener on the outer `section` element and get the most deeply nested element.
```js
const section = document.querySelector('section');

// Print the selected target

section.addEventListener('click', event => {
    console.log(event.target);
});
```
Clicking on any one of our `div` elements will return the output of the relevant specific element to the Console using `event.target`. This is extremely useful, as it allows you to place only one event listener that can be used to access many nested elements.

With the `Event` object, we can set up responses related to all events, including generic events and more specific extensions.

## Summary
Events are actions that take place on a website, such as clicking, hovering, submitting a form, loading a page, or pressing a key on the keyboard. JavaScript becomes truly interactive and dynamic when we are able to make websites respond to actions the user has taken.

In this tutorial, we learned what events are, examples of common events, the difference between event handlers and event listeners, and how to access the Event object. Using this knowledge, you will be ready to begin making dynamic websites and applications!

## Conclusion
If you liked this blog post, follow me on [Twitter](https://twitter.com/RembertDesigns) where I post daily about Tech related things!
![Buy Me A Coffee](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijinng8k7bf23v0o6gkj.png) If you enjoyed this article & would like to leave a tip — click [here](https://www.buymeacoffee.com/rembertdesigns)

### 🌎 Let's Connect

- [Portfolio](https://www.rembertdesigns.co/)

- [Twitter](https://twitter.com/RembertDesigns)

- [LinkedIn](https://www.linkedin.com/in/rrembert/)

- [Hashnode](https://rembertdesigns.hashnode.dev/)

- [Devto](https://dev.to/rembertdesigns)

- [Medium](https://medium.com/@rembertdesigns)

- [Github](https://github.com/rembertdesigns)

- [Codepen](https://codepen.io/rembertdesigns)