JavaScript FocusEvent relatedTarget Property: Understanding the Related Element

The FocusEvent interface in JavaScript provides specific information about focus-related events, such as when an element gains focus or loses it. Among its properties, the relatedTarget is particularly useful. It helps identify the element that is involved in the focus change, whether it is the element gaining or losing focus. This guide will delve into the details of the relatedTarget property, explaining its use cases and providing practical examples.

What is the relatedTarget Property?

The relatedTarget property of a FocusEvent object returns the element that is involved in a focus change. Specifically:

  • When a focus event occurs (i.e., an element gains focus), relatedTarget refers to the element that lost focus.
  • When a blur event occurs (i.e., an element loses focus), relatedTarget refers to the element that gained focus.

This property is null in cases where there is no related element, for example, when an element initially receives focus without a previous element having focus. It’s essential for developers to understand the context in which relatedTarget is used to correctly interpret the focus transitions.

Syntax of relatedTarget

The relatedTarget property is accessed directly from the FocusEvent object within the event handler:

event.relatedTarget;
  • event: The FocusEvent object dispatched during focus or blur events.
  • Returns: An Element representing the element that lost or gained focus or null if no related element is available.

Understanding FocusEvent

Before diving deeper, let’s recap the types of events where relatedTarget is used:

  1. focus: This event is fired when an element receives focus. The relatedTarget then points to the element that previously held focus (if any).
  2. blur: This event occurs when an element loses focus. The relatedTarget points to the element that receives the focus after this blur event.

Examples with relatedTarget

Let’s explore practical examples that illustrate the functionality of the relatedTarget property.

Basic Example with Focus and Blur Events

This example demonstrates how to capture the relatedTarget during focus and blur events on two input fields.

<input type="text" id="focusInput1" placeholder="Input 1" style="margin-bottom: 10px;"/>
<input type="text" id="focusInput2" placeholder="Input 2" />
<div id="focusOutput1" style="margin-top: 10px;"></div>

<script>
    const input1_focus = document.getElementById('focusInput1');
    const input2_focus = document.getElementById('focusInput2');
    const output1_focus = document.getElementById('focusOutput1');


    function handleFocus(event) {
      output1_focus.innerHTML += `<br>Focus on ${event.target.id}, related target: ${event.relatedTarget ? event.relatedTarget.id : 'null'}`;
    }

     function handleBlur(event) {
      output1_focus.innerHTML += `<br>Blur from ${event.target.id}, related target: ${event.relatedTarget ? event.relatedTarget.id : 'null'}`;
    }

    input1_focus.addEventListener('focus', handleFocus);
    input1_focus.addEventListener('blur', handleBlur);
    input2_focus.addEventListener('focus', handleFocus);
    input2_focus.addEventListener('blur', handleBlur);
</script>

In this code, when an input field gains focus, a message indicating the input field that gained focus and the relatedTarget (the element that lost focus, or null for initial focus) is shown in the output div. Similarly, when an input field loses focus, a message is added showing the input field that lost focus and the input that gained focus (relatedTarget).

Output (after interacting with the input fields):

Focus on focusInput1, related target: null
Blur from focusInput1, related target: focusInput2
Focus on focusInput2, related target: focusInput1
Blur from focusInput2, related target: focusInput1
Focus on focusInput1, related target: focusInput2

Example using Tabs

This example demonstrates how relatedTarget can be used when tabbing through different form elements.

<div id="container_focus_2" style="border: 1px solid #ddd; padding: 10px;">
  <input type="text" id="tabInput1" placeholder="Tab Input 1" style="margin-bottom: 5px; display:block;"/>
  <input type="text" id="tabInput2" placeholder="Tab Input 2" style="margin-bottom: 5px; display:block;"/>
  <button id="tabButton">Tab Button</button>
</div>
<div id="focusOutput2" style="margin-top: 10px;"></div>
<script>
  const container_focus2 = document.getElementById('container_focus_2');
  const output2_focus = document.getElementById('focusOutput2');

  container_focus2.addEventListener('focus', function(event) {
     output2_focus.innerHTML += `<br>Focus on ${event.target.id}, related target: ${event.relatedTarget ? event.relatedTarget.id : 'null'}`;
  }, true);

   container_focus2.addEventListener('blur', function(event) {
      output2_focus.innerHTML += `<br>Blur from ${event.target.id}, related target: ${event.relatedTarget ? event.relatedTarget.id : 'null'}`;
    }, true);
</script>

In this code, focus and blur events are captured at the container level using event capturing, and the relatedTarget is logged whenever an element within the container gains or loses focus.

Output (after interacting with the tab input fields):

Focus on tabInput1, related target: null
Blur from tabInput1, related target: tabInput2
Focus on tabInput2, related target: tabInput1
Blur from tabInput2, related target: tabButton
Focus on tabButton, related target: tabInput2
Blur from tabButton, related target: null

Example with Multiple Elements

This example shows using event delegation with multiple focusable elements:

<div id="focus_container_3" style="border: 1px solid #ddd; padding: 10px;">
    <button id="focusBtnA">Button A</button>
    <a href="#" id="focusLinkB">Link B</a>
    <input type="text" id="focusInputC" placeholder="Input C" />
</div>
<div id="focusOutput3" style="margin-top: 10px;"></div>
<script>
    const container3_focus = document.getElementById('focus_container_3');
    const output3_focus = document.getElementById('focusOutput3');
  container3_focus.addEventListener('focus', function(event) {
       output3_focus.innerHTML += `<br>Focus on ${event.target.id}, related target: ${event.relatedTarget ? event.relatedTarget.id : 'null'}`;
   }, true);

   container3_focus.addEventListener('blur', function(event) {
        output3_focus.innerHTML += `<br>Blur from ${event.target.id}, related target: ${event.relatedTarget ? event.relatedTarget.id : 'null'}`;
    }, true);
</script>

In this example, focus and blur events are delegated to the container, enabling you to track focus changes for multiple interactive elements using a single event listener.

Output (after interacting with elements):

Focus on focusBtnA, related target: null
Blur from focusBtnA, related target: focusLinkB
Focus on focusLinkB, related target: focusBtnA
Blur from focusLinkB, related target: focusInputC
Focus on focusInputC, related target: focusLinkB

When relatedTarget is null

The relatedTarget property will be null in the following cases:

  • Initial Focus: When an element initially receives focus, there isn’t a previously focused element, so relatedTarget is null.
  • Focus Loss: When focus is moved out of the browser window to the address bar or to other windows or applications.

Practical Use Cases

Here are some practical scenarios where relatedTarget can be incredibly useful:

  • Highlighting Focused Elements: You can use the relatedTarget to remove highlights from a previously focused element when a new element receives focus.
  • Implementing Focus Management: Use it to determine where focus should move to when navigating through complex forms or interfaces.
  • Tracking User Interaction: Log relatedTarget events to analyze user navigation patterns and identify areas for UI/UX improvements.
  • Custom Focus Effects: Create sophisticated focus transitions and animations using the relatedTarget to coordinate visual effects between elements.
  • Accessibility Enhancements: Utilize the property to manage the focus order, making the UI more accessible for keyboard navigation.

Browser Support

The relatedTarget property of the FocusEvent interface is well supported in all modern browsers, making it reliable for cross-browser web development. ✅

Conclusion

The FocusEvent‘s relatedTarget property provides essential insights into the focus state transitions between elements, allowing developers to create more interactive, user-friendly, and accessible web applications. By understanding how relatedTarget works, you can manage complex focus behaviors, enhance UI/UX, and improve overall web interaction. 🚀