DEV Community

Cover image for FocusEvent.relatedTarget — when and why you might need it.
Anuar Shaidenov
Anuar Shaidenov

Posted on

FocusEvent.relatedTarget — when and why you might need it.

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

Code structure for the to do list

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

Code for focus events

Code for deleting item from the To Do List

Code for attaching click event listener to the remove button

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

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

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

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.

Discussion (0)