Is there a cross-browser solution for monitoring when the document.activeElement changes?
Asked Answered
B

4

31

I'm really looking for something that works with all current popular browsers (IE9, Chrome, Firefox, Safari) and all the way back to IE8.

Although, I've been looking for a way to set focus on a Flash move object after it has lost focus, I've found that all historical ways of doing this fail. I assume it is yet another security issue.

So, I'm now looking for how to monitor change events of some sort for the document.activeElement (though "change" doesn't really occur).

Berrie answered 5/4, 2012 at 20:30 Comment(0)
P
21

While @James's answer above is correct. I've added more details to make it a completely working solution along with the use of focus event too.

<html>
<body>
    <input type="text" id="Text1" name ="Text1" value=""/>
    <input type="text" id="Text2" name ="Text2" value=""/>
    <SELECT><OPTION>ASDASD</OPTION><OPTION>A232</OPTION></SELECT>
    <INPUT TYPE="CHECKBOX" id="Check1"/>
    <INPUT type="TEXT" id="text3"/>
    <input type="radio"/>
    <div id="console"> </div>
    <textarea id="textarea1"> </textarea>
    <script>

        var lastActiveElement = document.activeElement;

        function detectBlur() {
            // Do logic related to blur using document.activeElement;
            // You can do change detection too using lastActiveElement as a history
        }

        function isSameActiveElement() {
            var currentActiveElement = document.activeElement;
            if(lastActiveElement != currentActiveElement) {
                lastActiveElement = currentActiveElement;
                return false;
            }

            return true;
        }

        function detectFocus() {
            // Add logic to detect focus and to see if it has changed or not from the lastActiveElement. 
        }

        function attachEvents() {
            window.addEventListener ? window.addEventListener('focus', detectFocus, true) : window.attachEvent('onfocusout', detectFocus);  

            window.addEventListener ? window.addEventListener('blur', detectBlur, true) : window.attachEvent('onblur', detectBlur);
        }

        attachEvents();

    </script>
</body>
</html>
Prather answered 28/1, 2015 at 14:30 Comment(1)
isSameActiveElement is redundantStodgy
F
8

It seems that you can use a combination of capturing focus/blur and focusin/focusout (IE) events. Something like this perhaps:

window.addEventListener ?
  window.addEventListener('blur', blurHappened, true)
  : window.attachEvent('onfocusout', blurHappened);

function blurHappened() {
  console.log('document.activeElement changed');
}

onfocusout will catch bubbled "blurs" while regular blur on addEventListener will capture "blurs".

You may need to add additional checks in blurHappened. I'm not sure as I haven't tested.

Figge answered 5/4, 2012 at 20:41 Comment(0)
M
4

You can capture a focus change on the document using the focusin event listener.

document.addEventListener('focusin', () => {
  console.log('focus changed');
});
div {
  display: flex;
  flex-direction: column;
}
<div>
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
  <input type="text">
</div>
Melleta answered 12/8, 2022 at 21:52 Comment(0)
P
1

In my experience, the best source of information on cross-browser issues is Quirksmode. Here's a link to the "obvious" (but not useable) option -- focus and blur events.

http://www.quirksmode.org/dom/events/blurfocus.html

Oddly (and surprisingly) it's Webkit-based browsers that are the fly in the ointment here.

Another option would be to use an interval timer to check whether the activeElement has changed either as your sole option OR as backup for focus/blur. (You could also listen for key presses, mouse clicks, and touches to check if activeElement changes.) If you cover these options, your intervalTimer will hardly ever need to clean up.

Peary answered 5/4, 2012 at 20:37 Comment(1)
I'm using an interval right now, but thought my ignorance was holding me back. Yet, searching for a while now and haven't found anything better. If I could take Flash out of the problem it would be easier. Awesome source, thank you!Berrie

© 2022 - 2024 — McMap. All rights reserved.