Проверьте, имеет ли окно фокус

Мне нужно проверить, есть ли у пользователя окна в фокусе, я сейчас делаю это:

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

И всякий раз, когда мне нужно проверить, есть ли у пользователя окна в фокусе, я просто делаю if(isonfocus==true).

Проблема: если пользователь теряет фокус перед загрузкой страницы, даже если я это сделаю if(isonfocus==true) он вернет true, хотя окно не находится в фокусе, и определение переменной var на false var isonfocus=false; будет делать обратное.

Может кто-нибудь мне помочь? Спасибо.

UPDATE
Представьте, что сайт PTC (платный клик), когда вы идете и выбираете рекламу для просмотра, большинство сайтов проверяют, действительно ли пользователь видит сайт рекламодателя (имеет фокус) или нет (потерянный фокус).
Это похоже на то, что мне нужно, мне нужен способ проверить, имеет ли пользователь окно (содержащее iframe) в фокусе.
Чтобы получить фокус, пользователь мог щелкнуть по iframe, документу или на вкладке.
Обратите внимание, что это необходимо для работы со всеми основными браузерами.

Ответ 1

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

Чтобы сделать его более эффективным, вам нужно var has_focus = false; и заставить пользователя щелкнуть где-нибудь на странице.

Ответ 2

Почему бы не использовать метод hasFocus, например.

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

Если вам нужно обрабатывать iframe, тогда ваш чек просто станет или, например,

function isFocused() {
    return document.hasFocus() || document.getElementById('iframe').contentWindow.document.hasFocus();
}

Ответ 3

Вы можете использовать document.visibilityState чтобы узнать, находится ли страница в фокусе или нет.

Ответ 4

Решение jQuery для перекрестного браузера!Следующий плагин проведет ваш стандартный тест для различных версий IE, Chrome, Firefox, Safari и т.д. И соответствующим образом определит ваши объявленные методы. В нем также рассматриваются такие вопросы, как:

  • Таймеры! ewwww!
  • onblur |.blur/onfocus |.фокус "дублировать" вызовы
  • окно, теряющее фокус через выбор альтернативного приложения, например слово
    • Это имеет тенденцию быть нежелательным просто потому, что если у вас открыта страница банка, и это событие onblur подсказывает ей замаскировать страницу, тогда, если вы откроете калькулятор, вы больше не увидите страницу!
  • Не запускать загрузку страницы

Использование выполняется так же, как:

$.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 & improved version, made for both vanilla and jQuery found here!


/*    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>

Ответ 5

Если вам не нужна поддержка Opera, вы можете получить лучшие результаты, используя метод document.hasFocus(). См. здесь для получения дополнительной информации об этом.

Ответ 6

Если у пользователя окно браузера сфокусировано/активно, но он только что нажал кнопку обновления (или строку URL и т.д.), document.hasFocus() сообщит вам, что окно не активно.

Тем не менее, вы можете вызвать window.focus() и посмотреть, действительно ли происходит событие focus. Если это так, браузер по-прежнему сфокусирован/активен.

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

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

  return hasFocus
}