SkyNT
SkyNT

Reputation: 803

Fire event only when focus is moved outside of any of an element's children

I want to fire an event when and only when the user focuses somewhere other than a child element of the div, e.g. when focus is transferred from input1 to input3:

<div onfocusout="console.log(document.activeElement)">
  <input type="text" id="input1">
  <input type="text" id="input2">
</div>

<input type="text" id="input3">

However, the focusout event is being triggered even when focus shifts within elements of the div, e.g. when focus is transferred from input1 to input2. To make matters worse, document.activeElement always resolves body at the instant focusout is triggered (suggesting that focus rolls all the way back to the body before moving back to input2) so I can't even manually verify where the new focus ends up before the focusout is triggered.

Upvotes: 7

Views: 2557

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370699

You can check the relatedTarget property of the event passed to the handler to see which element is getting the new focus:

const container = document.querySelector('#container');
container.addEventListener('focusout', (e) => {
  console.log(e.relatedTarget);
  if (!container.contains(e.relatedTarget)) console.log('focus is now outside of container');
});
<div id="container">
  <input type="text" id="input1">
  <input type="text" id="input2">
</div>

<input type="text" id="input3">

Upvotes: 8

Related Questions