43

I need to check if the user has windows on focus, I'm currently doing this:

var isonfocus=true;  
window.onblur = function(){  
  isonfocus=false;  
}  
window.onfocus = function(){  
  isonfocus=true;  
}

And whenever I need to check if the user has the windows on focus I just do if(isonfocus==true).

Problem: if the user loses focus before the page loads, even if I do if(isonfocus==true) it will return true, even though the window is not on focus, and defining the var to false var isonfocus=false; will do the reverse.

Can someone help me? Thanks.

UPDATE
Imagine a PTC (Paid-To-Click) site, when you go and click an ad to view, most sites verify if the user is actually seeing the advertiser site (has focus) or not (lost focus).
This is similar with what I need, I need a way to verify if the user has the window (which contains an iframe) on focus.
And to gain focus, the user could click the iframe, document or on the tab.
And please note that this needs to work on all major browsers.

  • 1
    The correct answer must be : http://stackoverflow.com/questions/1060008/is-there-a-way-to-detect-if-a-browser-window-is-not-currently-active – Jordan Mar 30 '15 at 22:05

7 Answers7

91

Use the hasFocus method:

if (document.hasFocus()) {
  // ...
}

If you have iframes on your page, they need to be checked separately:

function isFocused() {
  return document.hasFocus() || document.getElementById('iframe').contentWindow.document.hasFocus();
}
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
James
  • 80,725
  • 18
  • 167
  • 237
  • 9
    I need to check is the window has focus, not the document. –  Jun 30 '13 at 10:25
  • 1
    @user2536244 the documentation states "*Boolean value indicating whether the document or **any element inside** the document has focus*" - this will work for the window being focused as well. – James Jun 30 '13 at 10:30
  • It doesn't seem to work if the window has an iframe (clicking on the iframe to gain focus). –  Jun 30 '13 at 10:35
  • Well that sounds correct to me as an iframe is supposed to behave as a separate window. – James Jun 30 '13 at 10:37
  • 1
    Using Chrome, it gave me two errors: Blocked a frame with origin "xxx" from accessing a frame with origin "yyy". Protocols, domains, and ports must match. TypeError: Cannot call method 'hasFocus' of undefined –  Jun 30 '13 at 15:46
  • Ah that's Chrome's Cross Domain Request prevention kicking in - it would appear this approach wouldn't work for your particular scenario. You should maybe update your question so it's clear what your requirements are for other posters. – James Jun 30 '13 at 15:53
  • http://stackoverflow.com/questions/17656791/check-if-windows-page-document-iframe-has-focus –  Jul 15 '13 at 15:01
18

You can use document.visibilityState, which will be either 'visible' or 'hidden', to know whether the page is in focus or not.

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Dhirish
  • 321
  • 5
  • 14
  • 11
    Not true, unfortunately. `visibilityState` is `visible` unless the page is completely off-screen because the window is minimized, the user is in a different tab in the same window, or the display is off. Simply being occluded by another window still counts as "visible." – Christopher Swasey Jan 22 '19 at 21:12
  • In my case that's exactly what I needed and honestly when I read the question above, I believe that is the correct answer and it should be marked as such. There is no way with javascript to see if it is occluded by another window. – Ange Loron Feb 01 '19 at 15:22
  • see my answer below if you want to know if the browser is the active/focused window – kuceb Apr 26 '19 at 16:55
  • It looks like ```document.hasFocus()``` works on Windows, but does not work on Android if you switch into anoter app - the page still thinks it's in focus. So I had to use ```document.visibilityState == "visible"``` and it worked well on both in my case. Yours might be different. – Pavel Dec 08 '20 at 00:18
4
var has_focus = true;

function loading_time() {
    $(":focus").each(function() {
      if($(this).attr("id")=="iframeID") has_focus = true;
    });

    if(has_focus==true) alert('page has focus');
    else alert('page has not focus');

    setTimeout("loading_time()", 2000);
}

window.onblur = function(){  
    has_focus=false;  
}  
window.onfocus = function(){  
    has_focus=true;  
}

$(window).load(function(){
    setTimeout("loading_time()", 2000);
});

To make it more efficient, you need to var has_focus = false; and make the user click somewhere on the page.

1

The information in this topic is too old. Go ahead and use : document.hasFocus(). Now it will work for every browser you'll need.

Browser compatibility : https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus#browser_compatibility

Steve Moretz
  • 2,758
  • 1
  • 17
  • 31
0

If you don't care about Opera support you might get better results using the document.hasFocus() method. See here for more info on that.

intuitivepixel
  • 23,302
  • 3
  • 57
  • 51
  • 1
    I need to check is the window has focus, not the document. –  Jun 30 '13 at 10:27
  • For Opera you should write a `hasHasFocus` function: `function hasHasFocus() { return typeof document.hasFocus === 'function'; }` I just think the name is funny. – Patrick Roberts Aug 12 '15 at 22:07
0

Cross Browser jQuery Solution! The following plugin will go through your standard test for various versions of IE, Chrome, Firefox, Safari, etc.. and establish your declared methods accordingly. It also deals with issues such as:

  • timers! ewwww!
  • onblur|.blur/onfocus|.focus "duplicate" calls
  • window losing focus through selection of alternate app, like word
    • This tends to be undesirable simply because, if you have a bank page open, and it's onblur event tells it to mask the page, then if you open calculator, you can't see the page anymore!
  • Not triggering on page load

Use is as simple as:

$.winFocus(function(event, isVisible) {
    console.log("Combo\t\t", event, isVisible);
});

//  OR Pass False boolean, and it will not trigger on load,
//  Instead, it will first trigger on first blur of current tab_window
$.winFocus(function(event, isVisible) {
    console.log("Combo\t\t", event, isVisible);
}, false);

//  OR Establish an object having methods "blur" & "focus", and/or "blurFocus"
//  (yes, you can set all 3, tho blurFocus is the only one with an 'isVisible' param)
$.winFocus({
    blur: function(event) {
        console.log("Blur\t\t", event);
    },
    focus: function(event) {
        console.log("Focus\t\t", event);
    }
});

//  OR First method becoms a "blur", second method becoms "focus"!
$.winFocus(function(event) {
    console.log("Blur\t\t", event);
},
function(event) {
    console.log("Focus\t\t", event);
});

New&improvedversion,madeforbothvanillaandjQueryfoundhere!


/*    Begin Plugin    */
;;(function($){$.winFocus||($.extend({winFocus:function(){var a=!0,b=[];$(document).data("winFocus")||$(document).data("winFocus",$.winFocus.init());for(x in arguments)"object"==typeof arguments[x]?(arguments[x].blur&&$.winFocus.methods.blur.push(arguments[x].blur),arguments[x].focus&&$.winFocus.methods.focus.push(arguments[x].focus),arguments[x].blurFocus&&$.winFocus.methods.blurFocus.push(arguments[x].blurFocus),arguments[x].initRun&&(a=arguments[x].initRun)):"function"==typeof arguments[x]?b.push(arguments[x]):
"boolean"==typeof arguments[x]&&(a=arguments[x]);b&&(1==b.length?$.winFocus.methods.blurFocus.push(b[0]):($.winFocus.methods.blur.push(b[0]),$.winFocus.methods.focus.push(b[1])));if(a)$.winFocus.methods.onChange()}}),$.winFocus.init=function(){$.winFocus.props.hidden in document?document.addEventListener("visibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="mozHidden")in document?document.addEventListener("mozvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden=
"webkitHidden")in document?document.addEventListener("webkitvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="msHidden")in document?document.addEventListener("msvisibilitychange",$.winFocus.methods.onChange):($.winFocus.props.hidden="onfocusin")in document?document.onfocusin=document.onfocusout=$.winFocus.methods.onChange:window.onpageshow=window.onpagehide=window.onfocus=window.onblur=$.winFocus.methods.onChange;return $.winFocus},$.winFocus.methods={blurFocus:[],blur:[],focus:[],
exeCB:function(a){$.winFocus.methods.blurFocus&&$.each($.winFocus.methods.blurFocus,function(b,c){this.apply($.winFocus,[a,!a.hidden])});a.hidden&&$.winFocus.methods.blur&&$.each($.winFocus.methods.blur,function(b,c){this.apply($.winFocus,[a])});!a.hidden&&$.winFocus.methods.focus&&$.each($.winFocus.methods.focus,function(b,c){this.apply($.winFocus,[a])})},onChange:function(a){var b={focus:!1,focusin:!1,pageshow:!1,blur:!0,focusout:!0,pagehide:!0};if(a=a||window.event)a.hidden=a.type in b?b[a.type]:
document[$.winFocus.props.hidden],$(window).data("visible",!a.hidden),$.winFocus.methods.exeCB(a);else try{$.winFocus.methods.onChange.call(document,new Event("visibilitychange"))}catch(c){}}},$.winFocus.props={hidden:"hidden"})})(jQuery);
/*    End Plugin      */

// Simple example
$(function() {
 $.winFocus(function(event, isVisible) {
  $('td tbody').empty();
  $.each(event, function(i) {
   $('td tbody').append(
    $('<tr />').append(
     $('<th />', { text: i }),
     $('<td />', { text: this.toString() })
    )
   )
  });
  if (isVisible) 
   $("#isVisible").stop().delay(100).fadeOut('fast', function(e) {
    $('body').addClass('visible');
    $(this).stop().text('TRUE').fadeIn('slow');
   });
  else {
   $('body').removeClass('visible');
   $("#isVisible").text('FALSE');
  }
 });
})
body { background: #AAF; }
table { width: 100%; }
table table { border-collapse: collapse; margin: 0 auto; width: auto; }
tbody > tr > th { text-align: right; }
td { width: 50%; }
th, td { padding: .1em .5em; }
td th, td td { border: 1px solid; }
.visible { background: #FFA; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h3>See Console for Event Object Returned</h3>
<table>
    <tr>
        <th><p>Is Visible?</p></th>
        <td><p id="isVisible">TRUE</p></td>
    </tr>
    <tr>
        <td colspan="2">
            <table>
                <thead>
                    <tr>
                        <th colspan="2">Event Data <span style="font-size: .8em;">{ See Console for More Details }</span></th>
                    </tr>
                </thead>
                <tbody></tbody>
            </table>
        </td>
    </tr>
</table>
SpYk3HH
  • 22,272
  • 11
  • 70
  • 81
-6

If the user has the browser window focused/active, but has just clicked the refresh button (or url bar, etc), document.hasFocus() will tell you the window is not active.

However, you can call window.focus() and see if the focus event is actually fired. If it is, the browser is still focused/active.

const windowHasFocus = function () {
  if (document.hasFocus()) return true
  let hasFocus = false

  window.addEventListener('focus', function () {
    hasFocus = true
  })
  window.focus()

  return hasFocus
}

kuceb
  • 16,573
  • 7
  • 42
  • 56
  • 1
    Calling window.focus() will make a request to bring the window to the front. https://developer.mozilla.org/en-US/docs/Web/API/Window/focus – cameron.townsend Jun 21 '19 at 00:34