如何判断浏览器/选项卡是否处于活动状态

IT技术 javascript jquery
2021-02-07 14:46:51

可能的重复:
有没有办法检测浏览器窗口当前是否处于活动状态?

我有一个每秒调用一次的函数,如果当前页面在前台,我只想运行它,即用户没有最小化浏览器或切换到另一个选项卡。如果用户不看它并且可能是 CPU 密集型的,它就没有任何用处,所以我不想只是在后台浪费周期。

有谁知道如何在 JavaScript 中告诉这个?

注意:我使用 jQuery,所以如果你的答案使用它,那很好:)。

6个回答

除了Richard Simões 的回答之外,您还可以使用Page Visibility API

if (!document.hidden) {
    // do what you need
}

该规范为站点开发人员定义了一种以编程方式确定页面当前可见性状态的方法,以便开发高效且 CPU 高效的 Web 应用程序。

了解更多(2019 年更新)

+1 用于给出不依赖于 jQuery 的答案。从长远来看,这似乎也是最好的答案,因为浏览器正在朝着支持 W3C 标准的方向发展。David Walsh 的示例适用于 Chrome 和 Firefox,但不适用于 Safari。
2021-03-11 14:46:51
页面可见性 API 检测浏览器是否可见,例如未被最小化或完全被另一个窗口覆盖。它不会检测窗口可见但另一个窗口处于活动状态的情况。
2021-03-11 14:46:51
2021-03-19 14:46:51
可见性和焦点是完全不同的东西。
2021-03-20 14:46:51
@ckknight 你介意改变这个公认的答案吗?这个更新的答案是我们应该在 2019 年使用的答案
2021-04-05 14:46:51

您将使用窗口focusblur事件:

var interval_id;
$(window).focus(function() {
    if (!interval_id)
        interval_id = setInterval(hard_work, 1000);
});

$(window).blur(function() {
    clearInterval(interval_id);
    interval_id = 0;
});

回答“Double Fire”的评论问题并保持jQuery的易用性:

$(window).on("blur focus", function(e) {
    var prevType = $(this).data("prevType");

    if (prevType != e.type) {   //  reduce double fire issues
        switch (e.type) {
            case "blur":
                // do work
                break;
            case "focus":
                // do work
                break;
        }
    }

    $(this).data("prevType", e.type);
})

单击以查看显示它工作的示例代码 (JSFiddle)

这个答案不是最优的,因为对于用户采取的每个概念性 Focus 或 Blur 操作focusblur事件通常会在浏览器中触发多次以上,在这种情况下,客户端将hard_work在多个时间间隔内开始执行,基本上是同时进行的。
2021-03-12 14:46:51
我在其他地方读过,这onmousemove可能是focus.
2021-03-15 14:46:51
但是如果用户在页面加载时切换选项卡,之前$(window)focus/blur被调用怎么办?根据您的用例,这可能会弄乱回调状态和任何后台作业?(例如,如果您在页面加载时启动后台作业 - 但blur从未发生过,因为用户在$(window).blur注册之前切换了标签?)
2021-03-15 14:46:51
@MichaelRobinson 也许用于最大化/全屏选项卡式浏览器。它可能仍会在 Internet Explorer ( bit-tech.net/news/bits/2012/12/13/ie-bug-cursor/1 ) 中触发,尽管重点是其他一些应用程序。
2021-03-23 14:46:51
那行得通吗?测试?这么简单?
2021-03-24 14:46:51

我会尝试在window.onfocuswindow.onblur事件上设置一个标志

以下代码段已在 Firefox、Safari 和 Chrome 上进行了测试,打开控制台并在选项卡之间来回移动:

var isTabActive;

window.onfocus = function () { 
  isTabActive = true; 
}; 

window.onblur = function () { 
  isTabActive = false; 
}; 

// test
setInterval(function () { 
  console.log(window.isTabActive ? 'active' : 'inactive'); 
}, 1000);

在这里尝试一下

例子很棒。对 IE 有任何想法吗?
2021-03-19 14:46:51
出于某种原因,isActive 在 Chrome 上总是错误的?
2021-03-28 14:46:51
我可以确认它在 IE7 中运行良好,除此之外还没有测试过,这是最好的答案,也是所有功能相同的答案中的第一个答案,投票吧!
2021-03-29 14:46:51
我也喜欢这个简单的例子。我修复了一个小错字并添加了页面反馈 + jquery 以查看没有控制台的情况。jsbin.com/ulize3/80
2021-03-31 14:46:51
实际上,它在 Chrome 上始终为 false 的原因是因为console.log使用window.isActive. 移除window.零件或将其添加到任何地方。我也认为isActive应该初始化为 true 以获得更好的结果。
2021-04-05 14:46:51

使用jQuery:

$(function() {
    window.isActive = true;
    $(window).focus(function() { this.isActive = true; });
    $(window).blur(function() { this.isActive = false; });
    showIsActive();
});

function showIsActive()
{
    console.log(window.isActive)
    window.setTimeout("showIsActive()", 2000);
}

function doWork()
{
    if (window.isActive) { /* do CPU-intensive stuff */}
}

此处的所有示例(rockacola 的除外)都要求用户物理单击窗口以定义焦点。这并不理想,因此.hover()是更好的选择:

$(window).hover(function(event) {
    if (event.fromElement) {
        console.log("inactive");
    } else {
        console.log("active");
    }
});

这会告诉您用户何时将鼠标放在屏幕上,但它仍然不会告诉您它是否在用户的鼠标在其他地方的前景中。

此外,悬停取决于鼠标移动。如果选项卡是使用键盘快捷键输入的,则可能不会触发悬停。
2021-03-24 14:46:51
善于跳出思维定势;但是,如果您试图确定用户在页面上停留的时间,则效果不佳。此外,hover对于移动浏览器来说这不是一个有效的选项。公平地说,我不知道focusorblur事件绑定是否适用于移动设备。
2021-04-03 14:46:51