为什么我的 Chrome 扩展程序中从未收到 onCreated 事件的选项卡会收到 webNavigation.onCompleted 事件?

dan*_*hel 1 javascript google-chrome google-chrome-extension

我正在尝试编写一个 Chrome 扩展程序,以密切跟踪打开的各个选项卡。不过,似乎新标签不断凭空出现。这里发生了什么?

这是一个非常简单的背景页面,说明了我正在谈论的内容:

(function () {
    'use strict';

    var tabKeeper = {};

    function logError(tabId) {
        if (!tabKeeper[tabId]) {
            console.log('Tab ' + tabId + ' not found!');
            console.log(JSON.stringify(tabKeeper));
            tabKeeper[tabId] = true;
        }
    }

    chrome.tabs.onCreated.addListener((tab) => {
        console.log('Tab created: ' + tab.id);
        tabKeeper[tab.id] = true;
    });

    chrome.webNavigation.onCompleted.addListener((details) => {
        console.log('Navigation complete: ' + details.tabId);
        logError(details.tabId);
    });

    chrome.tabs.query({}, (tabs) => {
        if (!tabs) { return; }
        tabs.forEach((tab) => {
            console.log('Tab found at startup: ' + tab.id);
            tabKeeper[tab.id] = true;
        });
    });

})();
Run Code Online (Sandbox Code Playgroud)

重现行为的步骤(Chrome 47.0.2526.73):

  • 启动 Chrome
  • 创建一个新选项卡
  • 在新选项卡的地址栏中输入“abc”(后面有一个空格)

这是我在控制台日志中看到的内容:

Tab found at startup: 2
Navigation complete: 2
Tab created: 4
Navigation complete: 4
Navigation complete: 4
Navigation complete: 6
Tab 6 not found!
{"2":true,"4":true}
Run Code Online (Sandbox Code Playgroud)

这似乎是非常可重复的。选项卡 6 是什么?它从哪里来的?为什么我在创建事件时没有收到事件?

Nik*_*rma 5

这是由于Chrome Prerendering特性造成的。当您在地址栏中输入地址时,在实际打开选项卡之前,它会呈现为隐藏选项卡,当您按 Enter 键时,该选项卡就会可见。内容脚本和 Chrome 扩展程序对于这些隐藏选项卡也处于活动状态。它通过在任何用户实际访问内容之前保持内容准备就绪,从根本上加快了获得更好用户体验的过程。更多详细信息请参见此处

此外,了解任何页面的可见性状态如何变化对于理解调用这些事件的原因也非常有帮助。

这是触发事件但选项卡尚未打开且对您可见的基本原因。同样,当prerendering可见性状态发生变化时,chrome.tabs.onCreated.addListener()不会调用 ,但chrome.tabs.onReplaced()会调用另一个侦听器。有关页面可见性状态的更多详细信息,请参见此处