Detecting when an iframe gets or loses focus

前端 未结 9 1343
我寻月下人不归
我寻月下人不归 2020-12-31 06:24

What\'s the correct way of detecting when an iframe gets or loses focus (i.e. will or will not receive keyboard events)? The following is not working in Fx4:



        
9条回答
  •  萌比男神i
    2020-12-31 06:48

    How to check when an iframe has been clicked in or out of as well as hover-state.

    Note: I would highly recommend you don't choose a polling method and go with an event driven method such as this.


    Disclaimer

    It is not possible to use the focus or blur events directly on an iframe but you can use them on the window to provide an event driven method of checking the document.activeElement. Thus you can accomplish what you're after.

    Although we're now in 2018, my code is being implemented in GTM and tries to be cross browser compatible back to IE 11. This means there's more efficient code if you're utilizing newer ES/ECMAScript features.


    Setup

    I'm going to take this a few steps further to show that we can also get the iframe's src attribute as well as determine if it's being hovered.

    Code

    You would ideally need to put this in a document ready event, or at least encapsulate it so that the variables aren't global [maybe use an IIFE]. I did not wrap it in a document ready because it's handled by GTM. It may also depend where you place this or how you're loading it such as in the footer.

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

    I have noticed in the JSFiddle preview that it's already an iframe, sometimes you have to focus it first before events start to capture. Other issues can be that your browser window isn't yet focused either.

    // 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);
    }
    

提交回复
热议问题