Detect when iframe gains or loses focus

What is the correct way to detect when an iframe gains or loses focus (i.e. will or will not accept keyboard events)? In Fx4 does not work:

var iframe = /* my iframe */; iframe.addEventListener("focus", function() { /* never gets called */ }, false); 
+11
source share
8 answers

It turns out this is not real. I had to change the logic of my page to avoid the need for tracking if the iframe has focus.

+7
source

You can poll "document.activeElement" to determine if it matches the iframe. The survey is not perfect, but it works:

 function checkFocus() { if(document.activeElement == document.getElementsByTagName("iframe")[0]) { console.log('iframe has focus'); } else { console.log('iframe not focused'); } } window.setInterval(checkFocus, 1000); 
+22
source

I know this is old, but I also had the same problem.

i ended up with this little piece of code:

 $(document).on('focusout', function(){ setTimeout(function(){ // using the 'setTimout' to let the event pass the run loop if (document.activeElement instanceof HTMLIFrameElement) { // Do your logic here.. } },0); }); 
+9
source

How to check when an iframe was inserted or turned off, as well as hover state.

Note I highly recommend not choosing a polling method and using an event-driven method such as this one.


Denial of responsibility

It is not possible to use focus or blur events directly in an iframe, but you can use them in a window to provide an event-driven document.activeElement validation method. That way you can accomplish what you want.

Although we are now in 2018, my code is being implemented in GTM and is trying to be cross-browser compatible back in IE 11. This means there is more efficient code if you use the newer ES / ECMAScript features.


Customization

I'm going to take this a few steps further to show that we can also get the iframe src attribute and determine if it was displayed.

The code

Ideally, you need to put this in a document ready event, or at least encapsulate it so that the variables are not global [maybe use IIFE]. I did not wrap it in the finished document, because it is processed by GTM. It may also depend on where you place it or how you load it, for example in the footer.

https://jsfiddle.net/9285tbsm/9/

In the JSFiddle preview, I noticed that this is already an iframe, sometimes you need to focus it first before you start capturing events. Other problems may be due to the fact that your browser window is not yet focused.

 // Helpers var iframeClickedLast; function eventFromIframe(event) { var el = event.target; return el && el.tagName && el.tagName.toLowerCase() == 'iframe'; } function getIframeSrc(event) { var el = event.target; return eventFromIframe(event) ? el.getAttribute('src') : ''; } // Events function windowBlurred(e) { var el = document.activeElement; if (el.tagName.toLowerCase() == 'iframe') { console.log('Blurred: iframe CLICKED ON', 'SRC:', el.getAttribute('src'), e); iframeClickedLast = true; } else { console.log('Blurred', e); } } function windowFocussed(e) { if (iframeClickedLast) { var el = document.activeElement; iframeClickedLast = false; console.log('Focussed: iframe CLICKED OFF', 'SRC:', el.getAttribute('src'), e); } else { console.log('Focussed', e); } } function iframeMouseOver(e) { console.log('Mouse Over', 'SRC:', getIframeSrc(e), e); } function iframeMouseOut(e) { console.log('Mouse Out', 'SRC:', getIframeSrc(e), e); } // Attach Events window.addEventListener('focus', windowFocussed, true); window.addEventListener('blur', windowBlurred, true); var iframes = document.getElementsByTagName("iframe"); for (var i = 0; i < iframes.length; i++) { iframes[i].addEventListener('mouseover', iframeMouseOver, true); iframes[i].addEventListener('mouseout', iframeMouseOut, true); } 
+1
source

The solution is to inject a javascript event on the parent page as follows:

 var script = document.createElement('script'); script.type = 'text/javascript'; script.innerHTML = "document.addEventListener('click', function()" + "{ if(document.getElementById('iframe')) {" + // What you want "}});"; head.appendChild(script); 
0
source

Here is the code to detect when the iframe gains or loses focus

  // This code can be used to verify Iframe gets focus/loses. function CheckFocus(){ if (document.activeElement.id == $(':focus').context.activeElement.id) { // here do something } else{ //do something } } 
0
source

It can work

 document.addEventListener('click', function(event) { var frame= document.getElementById("yourFrameID"); var isClickInsideFrame = frame.contains(event.target); if (!isClickInsideFrame ) { //exec code } }); 
0
source

A compact function that accepts callbacks that you want to run when the iframe gains or loses focus.

 /* eslint-disable no-unused-vars */ export default function watchIframeFocus(onFocus, onBlur) { let iframeClickedLast; function windowBlurred(e) { const el = document.activeElement; if (el.tagName.toLowerCase() == 'iframe') { iframeClickedLast = true; onFocus(); } } function windowFocussed(e) { if (iframeClickedLast) { iframeClickedLast = false; onBlur(); } } window.addEventListener('focus', windowFocussed, true); window.addEventListener('blur', windowBlurred, true); } 
0
source

All Articles