如何使用Javascript在Chrome浏览器中检测标签是否处于焦点状态?


75

我需要知道用户当前是否在Google Chrome浏览器中查看标签页。我尝试使用事件模糊和焦点绑定到窗口,但是只有模糊似乎可以正常工作。

window.addEventListener('focus', function() {
  document.title = 'focused';
});

window.addEventListener('blur', function() {
  document.title = 'not focused';
});

焦点事件的工作很奇怪,仅在某些时候如此。如果我切换回另一个标签,则焦点事件将不会激活。但是,如果我单击地址栏,然后返回页面,它将。或者,如果我切换到另一个程序,然后再回到Chrome,则该选项卡当前处于焦点状态时它将激活。


您是否尝试将这些事件附加到docment而不是window
Crozin

我不确定它是否会影响事件检测,但是该window.focus操作在Chrome中被禁用(或至少存在错误)。看到这里这里更多。
brahn

也不与文档一起使用,这是针对焦点事件,而不是焦点动作。我想我将改变对此的处理方式,并将事件更改为鼠标悬停或窗口滚动。对于这种情况,这是适当的。
fent

从2011年起,您在问题中使用的代码在Chrome中可完美运行。该解决方案无效。
ninjagecko 2011年

Answers:


131

2015年更新:具有可见性API的新HTML5方式(摘自Blowsie的评论):

document.addEventListener('visibilitychange', function(){
    document.title = document.hidden; // change tab text for demo
})

从2011年起,原始海报提供的代码(已提出问题)现已生效:

window.addEventListener('focus', function() {
    document.title = 'focused';
});

window.addEventListener('blur', function() {
    document.title = 'not focused';
});

编辑:几个月后,在Chrome 14中仍然可以使用,但是用户必须至少单击一次窗口中的任何位置才能与页面进行交互。仅滚动并不足以使这项工作。这样window.focus()做也不会使这项工作自动进行。如果有人知道解决方法,请提及。


1
无需用户首先单击某个位置即可使其运行的方法是将“ window.focus()”添加到window.onload事件。这样做的副作用是,如果该窗口是链接的目标并且已经在当前窗口的后面打开,则它将被带到前面。请注意,此解决方案仅检测到焦点丢失,而不是由切换选项卡引起的。例如,如果失去焦点是由于用户在iframe中单击而造成的,则必须消除这种情况:
SPitBalls.com 2012年

<iframe ... onmouseover =“ iframeMouse(true)” onmouseout =“ iframeMouse(false)”> </ iframe>
SPitBalls.com 2012年

函数iframeMouse(over){oif = over; } window.addEventListener('blur',function(){document.title = oif?“ iframe focus”:“ not focus”;});
SPitBalls.com '02

5
有关更深入的可靠答案,请参见此。forums.greensock.com/topic/...
Blowsie

2
使用document.visibilityState来获取当前可见性状态
奥列格


2

毕竟它可能会起作用,我很好奇并编写了以下代码:

...
setInterval ( updateSize, 500 );
function updateSize(){
  if(window.outerHeight == window.innerHeight){
    document.title = 'not focused';             
  } else {
    document.title = 'focused';
  }

  document.getElementById("arthur").innerHTML = window.outerHeight + " - " + window.innerHeight;
}
...
<div id="arthur">
  dent
</div>

这段代码精确地完成了您想要的,但是很丑陋。事实是,Chrome似乎不时会忽略标题更改(当切换到选项卡并按住鼠标1秒钟似乎总是会产生这种效果)。

您将在屏幕上获得不同的值,但标题不会改变。

结论:无论您在做什么,测试时都不要相信结果!


标题对我来说立即更改。如果将事件更改为mouseover和mouseout,我会立即得到结果。
fent

无论如何,感谢(window.outerHeight == window.innerHeight)部分。对于这个特定的项目,我只需要知道用户当前是否专注。无需不断检查,您的代码即可正常工作。
芬特

2

对于想在模糊时交换页面标题,然后再回到焦点的原始页面标题的任何人:

// Swapping page titles on blur
var originalPageTitle = document.title;

window.addEventListener('blur', function(){
    document.title = 'Don\'t forget to read this...';
});

window.addEventListener('focus', function(){
    document.title = originalPageTitle;
});


0

这可以与JQuery一起使用

$(function() {
    $(window).focus(function() {
        console.log('Focus');
    });

    $(window).blur(function() {
        console.log('Blur');
    });
});

我认为这无济于事,因为正如他所报告的,浏览器不会触发您附加在“模糊”中的事件功能。因此,在您的示例中,console.log('Blur');在某些情况下不会调用代码。
psulek

-2

在Chrome中,你可以在不到1秒的超时运行后台脚本,而当标签没有焦点铬将只运行它的每一秒。例;

这在Firefox或Opera中不起作用。不了解其他浏览器,但我怀疑它是否也可以使用。

var currentDate = new Date();
var a = currentDate.getTime();

function test() {
    var currentDate = new Date();
    var b = currentDate.getTime();
var c = b - a;
    if (c > 900) {
        //Tab does not have focus.
    } else {
        //It does
    }
    a = b;
    setTimeout("test()",800);
}



setTimeout("test()",1);

2
我不喜欢对应该发生的事件使用间隔的想法。请注意,您应该使用setTimeout(test, 800)。如果给它一个字符串,它会的eval(),这要慢得多。
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.