1

Im trying to get the Boolean true if elements with a certain class name are focused on. But it seems Document.activeElement only works with either ID or Tag name, which wont help since they're elements of the same type. Heres the situation:

var test2 = document.getElementsByClassName('test2')
var test3 = document.getElementsByClassName('test3')

test3[1].focus()

isFocused2 = (document.activeElement === test2)
isFocused3 = (document.activeElement === test3)

document.getElementById('test').innerHTML = isFocused3
<input type="text" class="test2">
<input type="text" class="test3">
<input type="text" class="test2">
<input type="text" class="test3">

<div id="test"></div>

@Michael It works ONLY if the focus () is set to the input as you'll see below, but clicking on the input doesn't seem to make it active hence making the isFocused variable stay on false (my mistake in giving you the idea that i wanted to use that method to focus instead of clicking)

const prev = document.getElementsByClassName('prev');
const curr = document.getElementsByClassName('curr');

// curr[1].focus()

var isFocused1 = document.activeElement.classList.contains("prev");
var isFocused2 = document.activeElement.classList.contains("curr");


function fx2 () {
document.getElementById('test').innerHTML += isFocused1 + ' ' + isFocused2 + ' '
}
<table>
    <tr>
   <td><input type="text" name="" class="prev" onclick="fx2()"></td>
   <td><input type="text" name="" class="curr" onclick="fx2()"></td>
   <td><p class="Mtr-result"></p></td>
    </tr>
    <tr>
<td><input type="text" name="" class="prev" onclick="fx2()"></td>
<td><input type="text" name="" class="curr" onclick="fx2()"></td>
<td><p class="Mtr-result"></p></td>
    </tr>


<div  id="test"></div>

as you can see the focus method has been commented out, and the onclick event attribute on the input calls the fx2() function that changes the innerHTML value of the 'test' div to the value of isFocused 1 and 2, which both show false.

Michael M.
  • 10,486
  • 9
  • 18
  • 34
shuhei m
  • 67
  • 5

2 Answers2

1

document.activeElement works fine :

const test3 = document.querySelector('.test3');

document.querySelectorAll('input').forEach(el => {
  el.onfocus = state;
  el.onblur = state;
  function state() {
    document.getElementById('active-focus-class').innerHTML = document.activeElement.getAttribute('class');
    document.getElementById('test').innerHTML = document.activeElement === test3;
  }
})

test3.focus();
<input type="text" class="test1">
<input type="text" class="test2">
<input type="text" class="test3">
<input type="text" class="test4">

<p>.test3 is focused: <b id="test"></b>
<p>activeElement className: <b id="active-focus-class"></b>
imhvost
  • 4,750
  • 2
  • 8
  • 10
  • If the user clicks out of the input box, the focus doesn't update to reflect that. – Michael M. May 28 '23 at 21:29
  • Added a function call to the `onblur` event as well. – imhvost May 28 '23 at 21:33
  • I'd guess this approach isn't as effective (or at least, not as neat) as adding a two event handlers on `window` and letting the events bubble up. Adding two event handlers for every input box on the page isn't the best way. – Michael M. May 28 '23 at 21:46
  • Friend, if you can prove your point that my code is inefficient, I'll buy you a beer. So far, on the pledge of volunteerism, I have answered your question. – imhvost May 28 '23 at 21:55
  • 1
    learned about blur method, thx, the active focus class part was interesting, i did something similar but with a combo of ```if else``` and ```classlist.contain```. – shuhei m May 29 '23 at 20:20
  • There's no need to use `isSameNode`. Just compare directly. – Unmitigated Jun 02 '23 at 23:47
  • @Unmitigated , Yes you're right. Old habit. – imhvost Jun 04 '23 at 07:39
0

As Bergi and Zachiah pointed out in the comments, all you need to do is use document.activeElement.classList.contains("test2") to check if the focused element has the test2 class.

Element.classList.contains(class) is a method that you can call on any element, including document.activeElement. If the element you're calling it contains the class passed to the method, then it will return true, otherwise it will return false.

var test2 = document.getElementsByClassName('test2')
var test3 = document.getElementsByClassName('test3')

var isFocused2;
var isFocused3;

function fx() {
  isFocused2 = document.activeElement.classList.contains("test2")
  isFocused3 = document.activeElement.classList.contains("test3")

  document.getElementById('test').innerHTML = isFocused2 + ' ' + isFocused3;
}

window.addEventListener('focusin', fx);
window.addEventListener('focusout', fx);
<input type="text" class="test2">
<input type="text" class="test3">
<input type="text" class="test2">
<input type="text" class="test3">

<div id="test"></div>
Michael M.
  • 10,486
  • 9
  • 18
  • 34
  • I do appreciate the code, but it seems it only shows ```true``` if the focus method is added, please refer to the code above in the question. – shuhei m May 28 '23 at 20:35
  • @shuheim Always happy to help! If you want `isFocused2` and `isFocused3` to update whenever the focus on the page changes, then create an event handler for the `focusin` event on `window`, then update the variables from there. See my updated code. – Michael M. May 28 '23 at 21:28
  • Agreed that adding multiple handlers on every input seems to go against the DRY principle, however due to lack of other solutions i used it to solve a problem i was having with letting the arrow keys navigate input fields, adding ```onclick``` to ALL inputs. If you got a more efficient way i could message you the code? – shuhei m May 29 '23 at 20:19
  • Also, did you put the isFocused2 and 3 IN the function after i commented about the focus method? i completely missed that. – shuhei m May 29 '23 at 20:34
  • 1
    @shuheim Regarding `isFocused2` and `isFocused3`, I'm not entirely sure what you mean when you ask that, but you can read the [revision history](https://stackoverflow.com/posts/76349723/revisions) of my answer. Regarding the `onclick` event handlers, I'd be happy to help, however, the comment section is not the best place to do it. If you'd like you can [ask a new question](https://stackoverflow.com/questions/ask) or even just email me the code and any questions you have (see my user profile for my email). You might also want to google/research event propagation and event bubbling in JS. – Michael M. May 29 '23 at 20:40
  • https://stackoverflow.com/q/76360598/13713975 ( the new question ) – shuhei m May 29 '23 at 22:19