FocusEvent.relatedTarget — when and why you might need it.
Tags: javascript, webdev, css, html
Published: 2021-12-05 16:39:16


Last week I was working on a small to-do list app as a weekly project for a BootCamp for web developers that I’m enrolled in. The app is built with vanilla JavaScript, HTML/CSS for the UI. Although it is a “must” to have a to-do list app in front-end developers’ portfolio I’d never actually done it prior to this project and now I can see why people are saying how crucial it is for applying your skills into practice.

The features of the app were clear and seemingly simple:
1. Display list items dynamically
2. Save the data in the local storage
3. User should be able to add/remove items to/from the list
4. User should be able to edit the list items

![To do list app screensho](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x1alb4ue5s4l9xruxnru.png)

![Code structure for the to do list](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfae862mzm4lm6gimeev.png)

As you can see in the code above I used `<input type="text">` to display the description(name) of each task. The reason I chose to use it is to be able to edit the description and listen to the change event.

Throughout the process of building the app, I didn't really face any issues until I started working with `focusin` and `focusout` events alongside click events.

This was my thought process making this feature:
1. Attach `focusin` event listener to the input field
2. Apply styles (by adding classes)
3. Hide the options button and display the remove button (`display: none` and `display: block`).
4. On `focusout` event get everything back to the way it was
5. Attach the click event listener to the remove buttons
6. Remove the clicked item (match the `data-index` attribute with the `index` property of the item object in our list) then store and display the new list


![Code for hiding and unhiding the delete button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wn0cij715gwjugjxu70.png)


![Code for focus events](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mpl7koj4ekgvxgegy2x.png)


![Code for deleting item from the To Do List](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9cvdwloafxa5a6bp8q8i.png)


![Code for attaching click event listener to the remove button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5rp0azdfdgwnkw39lqx.png)

The edit mode was working as expected. As you can see the styles get applied and the button gets displayed when I go to the edit mode. And vice versa when I go out of focus of the input (click anywhere else in the document) the list items go to the initial state.

![To do list item in the edit mode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4fdgt7u0ayp9f2iyg70.png)

### Now this is where the problem takes place

As I said before we are setting our delete button to `display: none` on `focusout` which removes it from the DOM. When we try to click on that button the `focusout` event will fire and remove the element leaving us no chance of clicking on it and therefore deleting the list item. So how do we go around this bug?

After a lot of researching and testing, I figured out that I need to find a way to skip the step of hiding the remove button when it gets clicked.

If it was a click event we know that we could use ***ClickEvent.target*** to get the element that we click on. `Focusout` event is different though. It does not listen to clicks but it gets triggered whenever we go out of focus of the element the event is attached to.

Logging the event property I noticed the `relatedTarget` key and its value being the element that we click on.
![Console output for the event](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0kxrf3hdo28xo7yb0at0.png)

When we click on a blank space on the document we get `null` as a value, but if it's an element the value is the element that we click on.

From here we add our check to see if the clicked item contains the "btn-delete" class and we do nothing if it does(`return`), otherwise we just hide the button. Here's what our event listener would look like in the end.

![Screenshot of focusout event code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2b4q2kewwdgc2tedt3tw.png)

Viola! The bug has been fixed. Our to-do list app is now looking much better and cleaner and we can do whatever we want with it.