Chrome扩展程序的事件页面可以检测到浏览器启动完成的时间吗? [英] Can a Chrome extension's event page detect when the browser has finished starting up?

查看:102
本文介绍了Chrome扩展程序的事件页面可以检测到浏览器启动完成的时间吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Chrome扩展程序,它通过侦听与标签相关的事件(例如 tabs.onActivated onRemoved 等)来跟踪标签的访问顺序.事件页面,而不是用于添加事件侦听器的持久性背景页面.标签访问顺序存储在 chrome.storage.local 中.

I have a Chrome extension that tracks the order in which tabs are accessed by listening for tab-related events like tabs.onActivated, onRemoved, etc. It uses an event page instead of a persistent background page to add the event listeners. The tab access order is stored in chrome.storage.local.

在正常使用浏览器的过程中,扩展程序可以正常工作.但是,当Chrome首次启动并恢复上一个会话时,它将按照最初打开的顺序重新打开窗口,并为重新打开的标签页触发 onActivated 事件.

The extension works fine while in the normal course of using the browser. But when Chrome is first launched and restores the previous session, it reopens the windows in the order they were originally opened, firing onActivated events for the reopened tabs.

如果扩展名侦听了这些事件,它们将导致存储的选项卡访问顺序发生更改,而我试图避免这种情况.在Chrome完成还原会话并解决之前,我不想开始收听标签事件.但是我不确定如何使用事件页面来检测状态的变化,该事件页面通常在每次加载时都必须重新添加事件侦听器.

If the extension listened to these events, they would cause the stored tab access order to change, which I'm trying to avoid. I don't want to start listening to the tab events until Chrome has finished restoring the session and has settled down. But I'm not sure how to detect that change in state using an event page that normally has to re-add the event listeners every time it's loaded.

我尝试了以下类似的方法,以将添加选项卡事件侦听器的时间延迟到启动过程中创建完最后一个窗口之后不久(它侦听 windows.onCreated ,因为Chrome将在重新启动Windows时显示为背景,但此时未创建任何窗口):

I've tried something like the following to delay adding the tab event listeners until shortly after the last window has been created during startup (it listens for windows.onCreated because Chrome will start up in the background when you restart Windows, but no windows are created at that point):

var gStartingUp = false;

chrome.runtime.onStartup.addListener(() => {
    var timer = null;

    gStartingUp = true;

    chrome.windows.onCreated.addListener(window => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            gStartingUp = false;
            addListeners();
        }, 750);
    });
);

if (!gStartingUp) {
    addListeners();
}

通常情况下, gStartingUp 将默认设置为 false ,并且将添加侦听器.但是,当浏览器触发 onStartup 事件时,处理程序的调用速度不够快,无法阻止 addListeners()调用的发生,因此,侦听器也会在启动期间添加.我想我可以在调用 addListeners()之前添加一个超时,但这会在正常使用期间延迟添加它们.

In normal usage, gStartingUp would default to false and the listeners would get added. But when the browser fires the onStartup event, the handler isn't called fast enough to prevent the addListeners() call from happening, so the listeners are added during startup as well. I suppose I could add a timeout before calling addListeners(), but that would delay adding them during normal usage.

扩展程序的事件页面是否可以可靠地检测到Chrome已完成启动过程?

Is there a way for an extension's event page to reliably detect that Chrome has finished its startup processing?

推荐答案

我在下面的初始解决方案过于不可靠.我实际上看到了这样一种情况:Chrome重新启动,加载了事件页面,添加了侦听器的超时在100毫秒后触发,但是 onStartup 事件又没有触发整整两秒钟.

My initial solution below is too unreliable. I actually saw a case where Chrome restarted, the event page loaded, the timeout to add the listeners fired after 100ms, but the onStartup event didn't fire for another two whole seconds.

因此,我放弃了尝试延迟添加事件处理程序的尝试,直到处理完 onStartup 事件之后.相反,每个处理程序现在都会检查在 onStartup 处理程序中设置的 startingUp 标志,并且仅在事件不在启动阶段时才对其进行处理.该检查在扩展程序的整个生命周期中都是不必要的,但至少可以避免在处理事件之前增加人为的延迟.

So I gave up on trying to delay adding the event handlers until after the onStartup event was handled. Instead, each handler now checks a startingUp flag that's set in the onStartup handler, and only processes the event if it's not in the startup phase. That check is unnecessary for most of the lifetime of the extension, but it at least avoids adding an artificial delay before handling events.

在启动过程中,我还切换为侦听 tabs.onActivated 事件,因为Chrome似乎首先在启动过程中重新打开了窗口,然后重新打开了选项卡.因此,等待制表符激活暂停应该更好地表明Chrome已完成启动.

I also switched to listening for tabs.onActivated events during startup, as Chrome seems to reopen the windows first during startup, and then reopens the tabs. So waiting for a pause in tab activations should be a better signal that Chrome has finished starting up.

var startingUp = false;

chrome.runtime.onStartup.addListener(() => {
    var timer = null;

    startingUp = true;

    function onActivated()
    {
        clearTimeout(timer);
        timer = setTimeout(() => {
            startingUp = false;
            chrome.tabs.onActivated.removeListener(onActivated);
        }, 500);
    }

    chrome.tabs.onActivated.addListener(onActivated);
);

chrome.tabs.onActivated.addListener(tabID => {
    if (!startingUp) {
        // handle event
    }
});

初始解决方案

该问题的答案似乎是否".实际上,我能做的最好的事情就是延迟调用 addListeners()足够长的时间,以便在Chrome启动时触发 onStartup 侦听器:

Initial solution

The answer to that question would appear to be "no". The best I've been able to do is indeed delay calling addListeners() long enough for the onStartup listener to fire when Chrome is starting up:

var startingUp = false,
    addedListeners = false;

chrome.runtime.onStartup.addListener(() => {
    var timer = null;

    startingUp = true;

    chrome.windows.onCreated.addListener(window => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            startingUp = false;
            addListeners();
        }, 500);
    });
);

setTimeout(function() {
    if (!startingUp && !addedListeners) {
        addListeners();
    }
}, 100);

这似乎大部分可行,并且每次重新加载页面时添加事件处理程序的100ms延迟在实际使用中似乎并不明显(我尝试了0、10和50ms的延迟,但有时在 onStartup 处理程序之前触发).

This seems to mostly work, and the 100ms delay in adding event handlers every time the page is reloaded doesn't seem to be noticeable in actual usage (I've tried 0, 10 and 50ms delays, but they'd sometimes fire before the onStartup handler).

但是,如果时间到了,一切都会变得很混乱和脆弱.任何改进的解决方案都欢迎.

But it all feels very kludgy and brittle if the timing is off. Any improved solutions are welcome.

这篇关于Chrome扩展程序的事件页面可以检测到浏览器启动完成的时间吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆