Luk*_*ncl 560 javascript browser focus window
我有定期执行活动的JavaScript.当用户没有看到该站点时(即窗口或选项卡没有焦点),最好不要运行.
有没有办法使用JavaScript?
我的参考点:如果您使用的窗口未处于活动状态,则Gmail聊天会播放声音.
And*_*y E 664
自从最初撰写此答案以来,由于W3C ,新规范已达到推荐状态.在网页浏览权限API(在MDN)现在允许当一个页面被隐藏到用户我们更准确地检测.
目前的浏览器支持
以下代码使用API,回退到不兼容的浏览器中不太可靠的模糊/焦点方法.
document.addEventListener("visibilitychange", onchange);
Run Code Online (Sandbox Code Playgroud)
onfocusin并且onfocusout是IE 9及更低版本所必需的,而所有其他人都使用onfocus和onblur使用onpageshow和的iOS除外onpagehide.
小智 126
我会使用jQuery因为那样你所要做的就是:
$(window).blur(function(){
//your code here
});
$(window).focus(function(){
//your code
});
Run Code Online (Sandbox Code Playgroud)
或者至少它对我有用.
Jul*_*egg 44
有3种典型的方法用于确定用户是否可以看到HTML页面,但是它们都不能完美地工作:
在W3C网页浏览权限API应该做到这一点(支持,因为:火狐10,MSIE 10,铬13).但是,此API仅在完全覆盖浏览器选项卡时(例如,当用户从一个选项卡更改为另一个选项卡时)引发事件.当无法以100%的准确度确定可见性时,API不会引发事件(例如,Alt + Tab切换到另一个应用程序).
使用基于焦点/模糊的方法会给您带来很多误报.例如,如果用户在浏览器窗口顶部显示较小的窗口,则浏览器窗口将失去焦点(onblur凸起),但用户仍然能够看到它(因此仍需要刷新).另见http://javascript.info/tutorial/focus
为了改善上述不完美行为,我结合使用了3种方法:W3C Visibility API,然后是焦点/模糊和用户活动方法,以降低误报率.这允许管理以下事件:
这是它的工作原理:当文档松散焦点时,监视文档上的用户活动(例如鼠标移动)以确定窗口是否可见.页面可见性概率与页面上最后一次用户活动的时间成反比:如果用户长时间未对文档进行任何活动,则该页面很可能不可见.下面的代码模仿W3C页面可见性API:它的行为方式相同,但误报率很低.它具有多浏览器的优势(在Firefox 5,Firefox 10,MSIE 9,MSIE 7,Safari 5,Chrome 9上测试).
<div id="x"></div>
<script>
/**
Registers the handler to the event for the given object.
@param obj the object which will raise the event
@param evType the event type: click, keypress, mouseover, ...
@param fn the event handler function
@param isCapturing set the event mode (true = capturing event, false = bubbling event)
@return true if the event handler has been attached correctly
*/
function addEvent(obj, evType, fn, isCapturing){
if (isCapturing==null) isCapturing=false;
if (obj.addEventListener){
// Firefox
obj.addEventListener(evType, fn, isCapturing);
return true;
} else if (obj.attachEvent){
// MSIE
var r = obj.attachEvent('on'+evType, fn);
return r;
} else {
return false;
}
}
// register to the potential page visibility change
addEvent(document, "potentialvisilitychange", function(event) {
document.getElementById("x").innerHTML+="potentialVisilityChange: potentialHidden="+document.potentialHidden+", document.potentiallyHiddenSince="+document.potentiallyHiddenSince+" s<br>";
});
// register to the W3C Page Visibility API
var hidden=null;
var visibilityChange=null;
if (typeof document.mozHidden !== "undefined") {
hidden="mozHidden";
visibilityChange="mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden="msHidden";
visibilityChange="msvisibilitychange";
} else if (typeof document.webkitHidden!=="undefined") {
hidden="webkitHidden";
visibilityChange="webkitvisibilitychange";
} else if (typeof document.hidden !=="hidden") {
hidden="hidden";
visibilityChange="visibilitychange";
}
if (hidden!=null && visibilityChange!=null) {
addEvent(document, visibilityChange, function(event) {
document.getElementById("x").innerHTML+=visibilityChange+": "+hidden+"="+document[hidden]+"<br>";
});
}
var potentialPageVisibility = {
pageVisibilityChangeThreshold:3*3600, // in seconds
init:function() {
function setAsNotHidden() {
var dispatchEventRequired=document.potentialHidden;
document.potentialHidden=false;
document.potentiallyHiddenSince=0;
if (dispatchEventRequired) dispatchPageVisibilityChangeEvent();
}
function initPotentiallyHiddenDetection() {
if (!hasFocusLocal) {
// the window does not has the focus => check for user activity in the window
lastActionDate=new Date();
if (timeoutHandler!=null) {
clearTimeout(timeoutHandler);
}
timeoutHandler = setTimeout(checkPageVisibility, potentialPageVisibility.pageVisibilityChangeThreshold*1000+100); // +100 ms to avoid rounding issues under Firefox
}
}
function dispatchPageVisibilityChangeEvent() {
unifiedVisilityChangeEventDispatchAllowed=false;
var evt = document.createEvent("Event");
evt.initEvent("potentialvisilitychange", true, true);
document.dispatchEvent(evt);
}
function checkPageVisibility() {
var potentialHiddenDuration=(hasFocusLocal || lastActionDate==null?0:Math.floor((new Date().getTime()-lastActionDate.getTime())/1000));
document.potentiallyHiddenSince=potentialHiddenDuration;
if (potentialHiddenDuration>=potentialPageVisibility.pageVisibilityChangeThreshold && !document.potentialHidden) {
// page visibility change threshold raiched => raise the even
document.potentialHidden=true;
dispatchPageVisibilityChangeEvent();
}
}
var lastActionDate=null;
var hasFocusLocal=true;
var hasMouseOver=true;
document.potentialHidden=false;
document.potentiallyHiddenSince=0;
var timeoutHandler = null;
addEvent(document, "pageshow", function(event) {
document.getElementById("x").innerHTML+="pageshow/doc:<br>";
});
addEvent(document, "pagehide", function(event) {
document.getElementById("x").innerHTML+="pagehide/doc:<br>";
});
addEvent(window, "pageshow", function(event) {
document.getElementById("x").innerHTML+="pageshow/win:<br>"; // raised when the page first shows
});
addEvent(window, "pagehide", function(event) {
document.getElementById("x").innerHTML+="pagehide/win:<br>"; // not raised
});
addEvent(document, "mousemove", function(event) {
lastActionDate=new Date();
});
addEvent(document, "mouseover", function(event) {
hasMouseOver=true;
setAsNotHidden();
});
addEvent(document, "mouseout", function(event) {
hasMouseOver=false;
initPotentiallyHiddenDetection();
});
addEvent(window, "blur", function(event) {
hasFocusLocal=false;
initPotentiallyHiddenDetection();
});
addEvent(window, "focus", function(event) {
hasFocusLocal=true;
setAsNotHidden();
});
setAsNotHidden();
}
}
potentialPageVisibility.pageVisibilityChangeThreshold=4; // 4 seconds for testing
potentialPageVisibility.init();
</script>
由于目前没有可用的跨浏览器解决方案而没有误报,因此您最好三思而后行,禁用网站上的定期活动.
omn*_*nom 25
GitHub上有一个整洁的库:
https://github.com/serkanyersen/ifvisible.js
例:
// If page is visible right now
if( ifvisible.now() ){
// Display pop-up
openPopUp();
}
Run Code Online (Sandbox Code Playgroud)
我已经在我拥有的所有浏览器上测试了版本1.0.1,并且可以确认它适用于:
......可能还有所有新版本.
不完全适用于:
.now()始终true为我返回)小智 17
我为我的应用程序创建了Comet Chat,当我收到来自其他用户的消息时,我使用:
if(new_message){
if(!document.hasFocus()){
audio.play();
document.title="Have new messages";
}
else{
audio.stop();
document.title="Application Name";
}
}
Run Code Online (Sandbox Code Playgroud)
l2a*_*lba 17
使用: 页面可见性API
document.addEventListener( 'visibilitychange' , function() {
if (document.hidden) {
console.log('bye');
} else {
console.log('well back');
}
}, false );
Run Code Online (Sandbox Code Playgroud)
我可以用吗 ? http://caniuse.com/#feat=pagevisibility
Dan*_*ter 12
我开始使用社区维基回答,但意识到它没有检测到Chrome中的alt-tab事件.这是因为它使用了第一个可用的事件源,在这种情况下,它是页面可见性API,在Chrome中似乎不跟踪alt-tabbing.
我决定稍微修改脚本以跟踪页面焦点更改的所有可能事件.这是一个你可以参与的功能:
function onVisibilityChange(callback) {
var visible = true;
if (!callback) {
throw new Error('no callback given');
}
function focused() {
if (!visible) {
callback(visible = true);
}
}
function unfocused() {
if (visible) {
callback(visible = false);
}
}
// Standards:
if ('hidden' in document) {
document.addEventListener('visibilitychange',
function() {(document.hidden ? unfocused : focused)()});
}
if ('mozHidden' in document) {
document.addEventListener('mozvisibilitychange',
function() {(document.mozHidden ? unfocused : focused)()});
}
if ('webkitHidden' in document) {
document.addEventListener('webkitvisibilitychange',
function() {(document.webkitHidden ? unfocused : focused)()});
}
if ('msHidden' in document) {
document.addEventListener('msvisibilitychange',
function() {(document.msHidden ? unfocused : focused)()});
}
// IE 9 and lower:
if ('onfocusin' in document) {
document.onfocusin = focused;
document.onfocusout = unfocused;
}
// All others:
window.onpageshow = window.onfocus = focused;
window.onpagehide = window.onblur = unfocused;
};
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
onVisibilityChange(function(visible) {
console.log('the page is now', visible ? 'focused' : 'unfocused');
});
Run Code Online (Sandbox Code Playgroud)
adr*_*anu 11
这适用于所有现代浏览器:
var eventName;
var visible = true;
var propName = "hidden";
if (propName in document) eventName = "visibilitychange";
else if ((propName = "msHidden") in document) eventName = "msvisibilitychange";
else if ((propName = "mozHidden") in document) eventName = "mozvisibilitychange";
else if ((propName = "webkitHidden") in document) eventName = "webkitvisibilitychange";
if (eventName) document.addEventListener(eventName, handleChange);
if ("onfocusin" in document) document.onfocusin = document.onfocusout = handleChange; //IE 9
window.onpageshow = window.onpagehide = window.onfocus = window.onblur = handleChange;// Changing tab with alt+tab
// Initialize state if Page Visibility API is supported
if (document[propName] !== undefined) handleChange({ type: document[propName] ? "blur" : "focus" });
function handleChange(evt) {
evt = evt || window.event;
if (visible && (["blur", "focusout", "pagehide"].includes(evt.type) || (this && this[propName]))){
visible = false;
console.log("Out...")
}
else if (!visible && (["focus", "focusin", "pageshow"].includes(evt.type) || (this && !this[propName]))){
visible = true;
console.log("In...")
}
}
Run Code Online (Sandbox Code Playgroud)
这在 chrome 67、firefox 67 上对我有用,
if(!document.hasFocus()) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
这真的很棘手.鉴于以下要求,似乎没有解决方案.
这是因为:
鉴于这些限制,可以实现一个结合的解决方案 - 页面可见性API - 窗口模糊/焦点 - document.activeElement
这能够:
当iframe具有焦点时,您的模糊/焦点事件根本不会被调用,并且页面Visibility API将不会在alt + tab上触发.
我在@建AndyE的解决方案,并在这里实现这个(差不多好了)的解决方案: https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test1.html (对不起,我遇到了一些麻烦的jsfiddle).
这也可以在Github上找到:https://github.com/qmagico/estante-components
这适用于铬/铬.它类似于firefox,除了它不加载iframe内容(任何想法为什么?)
无论如何,要解决最后一个问题(4),你唯一能做的就是在iframe上监听模糊/焦点事件.如果您对iframe有一定的控制权,则可以使用postMessage API来执行此操作.
https://dl.dropboxusercontent.com/u/2683925/estante-components/visibility_test2.html
我还没有用足够的浏览器测试过这个.如果您可以找到有关这不起作用的更多信息,请在下面的评论中告诉我们.
在 HTML 5 中,您还可以使用:
onpageshow: 窗口可见时运行的脚本onpagehide: 窗口隐藏时运行的脚本看:
var visibilityChange = (function (window) {
var inView = false;
return function (fn) {
window.onfocus = window.onblur = window.onpageshow = window.onpagehide = function (e) {
if ({focus:1, pageshow:1}[e.type]) {
if (inView) return;
fn("visible");
inView = true;
} else if (inView) {
fn("hidden");
inView = false;
}
};
};
}(this));
visibilityChange(function (state) {
console.log(state);
});
Run Code Online (Sandbox Code Playgroud)
http://jsfiddle.net/ARTsinn/JTxQY/
这对我有用
document.addEventListener("visibilitychange", function() {
document.title = document.hidden ? "I'm away" : "I'm here";
});
Run Code Online (Sandbox Code Playgroud)
演示:https : //iamsahilralkar.github.io/document-hidden-demo/
| 归档时间: |
|
| 查看次数: |
252107 次 |
| 最近记录: |