The Cross-Browser Window Focus Blues

By on October 13, 2008 12:01 am

So your cool new app is perfect, but you want it to lock the user out when the browser hasn’t had focus after 15 minutes? Well that’s easy you think, I’ll just connect to the document’s blur and focus events and be good to go. You quickly add a little bit of code to your Dojo widget:

     dojo.connect(dojo.doc, "onblur", this, "onWindowBlur");
     dojo.connect(dojo.doc, "onfocus", this, "onWindowFocus");

That should do it you’d think. Launch your app with Firefox and everything is great, easy enough. The same is true with Safari. After reluctantly firing up your Virtual Machine to test Internet Explorer 6, much to your dismay, onfocus events are immediately followed by onfocusout events. You feel the harsh reality that IE6 is going to suck away a bit more of your life.

My new patch of gray hair is further evidence that I feel your pain.

Fortunately, while the solution seems to be difficult to track down on the “interwebs”, it is in fact pretty simple. The key is to understand that IE tracks the activeElement (document.activeElement) and fires onfocus and onfocusout events as the activeElement changes. As the onfocusout events occur, you must track what the activeElement is. When an onfocusout event happens and the activeElement doesn’t change, then the window has lost focus.

Take a look at the solution for IE:

        dojo.connect(dojo.global, "onfocus", this, "onWindowFocus");
        dojo.connect(dojo.doc, "onfocusout", this, function() {
             if (this._activeElement != document.activeElement){
                    this._activeElement = document.activeElement;
             }else{
                    this.onWindowBlur()
             }
        });

That’s not too bad at all. Here is is a cross browser compatible version:

if (dojo.isIE) {
   dojo.connect(dojo.global, "onfocus", this, "onWindowFocus");
        dojo.connect(dojo.doc, "onfocusout", this, function() {
             if (this._activeElement != document.activeElement){
                    this._activeElement = document.activeElement;
             }else{
                    this.onWindowBlur()
             }
        });
 }else{
    dojo.connect(dojo.doc, "onblur", this, "onWindowBlur");
    dojo.connect(dojo.doc, "onfocus", this, "onWindowFocus");
 }

There you go. Now you have time to play with your kids, get in a round of golf, and save a little bit of your life force for your next battle with Internet Explorer 6.

Comments

  • Pingback: Uxebu.com - JavaScript addicts » The Cross-Browser Window Focus Blues()

  • Pingback: Ajaxian » Fixing Loss of Focus on IE()

  • lebaron

    Hello,

    We have tested further your solution and it seems that for IE we catch more focus events, when the onfocusin event is also connected. Eg :

    if (dojo.isIE) {
    dojo.connect(dojo.global, “onfocusin”, this, “onWindowFocus”);
    dojo.connect(dojo.global, “onfocus”, this, “onWindowFocus”);
    […]

    But we still have a problem with iframes : when an iframe is focused and a

  • lebaron

    Sorry, I send the previous mail erroneously

    So I was writing that : when an iframe in a browser tab looses the focus when for example anoter window or tab browser is opened and then the tab containing the iframe is focused again, IE doesn’t send any focus event.

    Best regards

  • How do I make it to work for browser back button or outside the Frame clicks?

    Thank you

  • Seems to work with every browser except Safari 4 for me !
    Any fix?

  • Well I did now

    if (dojo.isIE) {
    dojo.connect(dojo.global, “onfocus”, this, “onWindowFocus”);
    dojo.connect(dojo.doc, “onfocusout”, this, function() {
    if (this._activeElement != document.activeElement){
    this._activeElement = document.activeElement;
    }else{
    this.onWindowBlur()
    }
    });
    } else if (dojo.isSafari) {
    window.onblur = onWindowBlur;
    window.onfocus = onWindowFocus;
    }else{
    dojo.connect(dojo.doc, “onblur”, this, “onWindowBlur”);
    dojo.connect(dojo.doc, “onfocus”, this, “onWindowFocus”);
    }

  • shailesh

    Hi,

    I tried “onfocus” and “onfocusout” events with plain javascript and they work fine with IE8 and 9 but with IE10 I am facing issue that “onfocusout” active element logic is not working anymore.

    Thanks,
    Shailesh