WebExtension:重新加载选项卡时反应 [英] WebExtension: React when a a tab is reloaded

查看:198
本文介绍了WebExtension:重新加载选项卡时反应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Firefox WebExtension,它具有弹出窗口,并使用 chrome.storage.local 来存储状态。到目前为止,我已经使用标签ID来存储特定标签的数据。

I am working on a Firefox WebExtension which has a popup and uses chrome.storage.local to store state. So far, I have got it to store data for specific tabs using the tab id.

如果当前选项卡被重新加载,我想重新初始化本地存储。这是因为扩展可能已经对DOM进行了一些更改,如果该标签被重新加载将会丢失;因此,它存储的状态是不正确的。

I would like to reinitialize the local storage if the current tab is reloaded. This is because the extension may have made some changes to the DOM which will be lost if the tab is reloaded; what state it has stored is therefore incorrect.

从弹出窗口调用初始JavaScript代码。

The initial JavaScript code is called from the popup.

谢谢

推荐答案

p>没有更多关于你的信息,你想要做什么,很难确定最好的方式来做到这一点。特别是很难准确地知道你想要回应什么情况。

Without more information from you as to exactly what you desire to do, it is difficult to determine the best way to do this. In particular, it is hard to know exactly what situations to which you desire to respond.

看起来你可以使用一个监听器 tabs.onUpdated 事件。虽然这种情况比您实际需要的频率更高,但是它会在重新加载页面时触发。

It looks like you could use a listener to the tabs.onUpdated event. While this fires more often than you actually desire, it does fire on reloading of a page.

以下是调用函数的代码 completedLoadingURLInTab() 当URL被加载或重新加载在页面上时。我已经留下了一堆 console.log()调用作为我通常会删除的注释。它们可以在事件触发时一直在控制台中显示。这可以用于确定从事件接收到的数据的内容以及在各种页面导航期间触发的事件序列。

Below is code that calls a function completedLoadingURLInTab() when a URL has been loaded, or reloaded on a page. I've left in a bunch of console.log() calls as comments which I would normally remove. They can be uncommented to show in the console all the times the event fires. This can be useful to determine exactly the contents of the data received from the event and the sequence of events that fire during various page navigation.

注1: / strong>我发现 changeInfo 对象在某些情况下可能无效。有必要使用 hasOwnProperty() ,然后从 tabs.Tab 对象也被传递给事件处理程序。
注2:需要 manifest.json 中的选项卡权限。

Note 1: I found that the changeInfo object can be invalid under some circumstances. It was necessary to see if a property existed using hasOwnProperty() and then obtain the value from the tabs.Tab object that is also passed to the event handler.
Note 2: The tabs permission in manifest.json is required.

function completedLoadingURLInTab(tabId, newUrl,oldUrl) {
    //We have completed, loading a URL.
    if(newUrl === oldUrl) {
        //We re-loaded the previous URL
        console.log(">>>>>>> Re-load tab=" + tabId + " with URL=" + newUrl);
    } else {
        //This URL _may_ be just a new position in the same page.  That
        //  is something that needs to be checked for here.
        console.log(">>>>>>> New URL loaded in tab=" + tabId + ". URL=" + newUrl);
    }

    //Remember the newUrl so we can check against it the next time
    //  an event is fired.
    tabsInfo[tabId].previousCompleteUrl = newUrl;
    tabsInfo[tabId].loadingUrl = newUrl;
}

let tabsInfo = {};
function InfoForTab(_loadingUrl,_previousUrl,_status) {
    this.loadingUrl = _loadingUrl;
    this.previousCompleteUrl = (_previousUrl === undefined) ? "" : _previousUrl;
    this.status = (_status === undefined) ? "" : _status;
}

function foundNewTab(tabId) {
    //Create an object to hold the collected info for the tab.
    tabsInfo[tabId] = new InfoForTab();
    console.log("New tab. ID=" + tabId);
}

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    if(!tabsInfo.hasOwnProperty(tabId)) {
        //This is the first time we have encountered this tab.
        foundNewTab(tabId);
    }
    let output="";
    //We use the properties of "tab" instead of "changeInfo" because in testing it was
    //  clear that changeInfo was not always properly populated. The key(s) may just
    //  exist, but not have any value associated with them.

    /*
    //Testing output showing when the event is fired.
    //  This is used to determine, by experimentation, what events to ignore and which
    //  combinations and sequence of events occur during page navigation.
    output += (changeInfo.hasOwnProperty("status")) ? "\nstatus=" + tab.status : "";
    output += (changeInfo.hasOwnProperty("url")) ? "\nurl=" + tab.url : "";
    output += (changeInfo.hasOwnProperty("pinned")) ? "\npinned=" + tab.pinned : "";
    output += (changeInfo.hasOwnProperty("audible")) ? "\naudible=" + tab.audible : "";
    output += (changeInfo.hasOwnProperty("mutedInfo")) ? "\nmutedInfo="+tab.mutedInfo : "";
    output +=(changeInfo.hasOwnProperty("favIconUrl"))?"\nfavIconUrl="+tab.favIconUrl : "";
    console.log("tabs.updated event: tabId=" + tabId + ":: changeInfo="
                + Object.keys(changeInfo) + output
    );
    */
    if(changeInfo.hasOwnProperty("status") && changeInfo.hasOwnProperty("url")
        && (tab.status === "loading")) {
        //A URL is being loaded into the tab. This can be for the first time,
        //  or transitioning to a new URL, or reloading the page.
        let outputFirst = "";
        let outputLoading = "Loading";
        if(tabsInfo[tabId].previousCompleteUrl === tab.url) {
            //We are re-loading the same URL
            outputLoading = "Re-loading";
        }
        //console.log(outputLoading  + " URL=" + tab.url);
        //We save the URL which is being loaded, but we really don't do anything with it.
        tabsInfo[tabId].loadingUrl = tab.url;
        tabsInfo[tabId].status = "loading";
        return;
    } //else
    if(changeInfo.hasOwnProperty("status") && (tab.status === "complete")) {
        if( tabsInfo[tabId].status === "loading") {
            tabsInfo[tabId].status = "complete";
            //console.log("In tabId="+tabId+" completed loading URL="+tab.url);
            completedLoadingURLInTab(tabId, tab.url, tabsInfo[tabId].previousCompleteUrl);
            return;
        } //else
        if( tabsInfo[tabId].status === "complete") {
            if(tabsInfo[tabId].previousCompleteUrl === tab.url) {
                //console.log("In tabId=" + tabId + " got completed status change after"
                //              + "already complete with URL="
                //              + tabsInfo[tabId].previousCompleteUrl);
                return;
            }//else
            //console.log("In tabId=" + tabId + " completed directly loading new URL="
            //            + tab.url);
            completedLoadingURLInTab(tabId, tab.url, tabsInfo[tabId].previousCompleteUrl);
            return;
        }
    }//else
    if(changeInfo.hasOwnProperty("status") && (tab.status === "loading")
        && ( tabsInfo[tabId].status === "complete")) {
        //console.log("In tabId=" + tabId + " leaving page");
        return;
    }//else
    if(changeInfo.hasOwnProperty("status") ) {
        if((tab.status === "complete") && (tab.url === "about:newtab")
            && tabsInfo[tabId].loadingUrl === undefined ) {
            //We have completed loading about:newtab for the first time in this tab.
            tabsInfo[tabId].status = "complete";
            completedLoadingURLInTab(tabId, tab.url, tabsInfo[tabId].previousCompleteUrl);
            return;
        } //else
        //console.log("In tabId=" + tabId + " got status change to " + tab.status
        //              + " prior to loading a URL with current URL=" + tab.url);
        return;
    }//else
});

加载附加组件,打开一个新的选项卡并进行一些导航(包括几个页面重新加载),控制台中的输出可能如下所示:

Given loading the add-on, opening a new tab and doing a bit of navigation (including a few page re-loads), the output in the console could look like:

New tab. ID=6
>>>>>>> New URL loaded in tab=6. URL=about:newtab
>>>>>>> New URL loaded in tab=6. URL=https://www.google.com/?gws_rd=ssl
>>>>>>> Re-load tab=6 with URL=https://www.google.com/?gws_rd=ssl
>>>>>>> New URL loaded in tab=6. URL=https://www.google.com/?gws_rd=ssl#q=test
>>>>>>> Re-load tab=6 with URL=https://www.google.com/?gws_rd=ssl#q=test
>>>>>>> New URL loaded in tab=6. URL=https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/Tabs/onUpdated
>>>>>>> New URL loaded in tab=6. URL=https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/Tabs/onUpdated#changeInfo
>>>>>>> Re-load tab=6 with URL=https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/Tabs/onUpdated#changeInfo



或者,使用 webNavigation 事件



webNavigation 事件直接提供有关网页导航的信息。他们可能会为您提供比 tabs.onUpdated 更好的解决方案。

Alternately, use the webNavigation events

The webNavigation events provide you information directly about web navigation. They will probably provide you with a better solution than tabs.onUpdated.

如果您使用 webNavigation 事件,您将需要进行实验,以查看您关心的情况下哪些组合的事件发生。很可能这将是 已完成 和/或 ReferenceFragmentUpdated

If you use webNavigation events, you will need to experiment to see which combination of events fire for the situations your are concerned about. Most likely this will be Completed and/or ReferenceFragmentUpdated.

所以你可以感受到什么当这些事件触发时,以下代码将登录到控制台全部 webNavigation 事件:

So you can get a feel for what when these events fire, the following code will log to the console all webNavigation events:

var webNavEvents = ['BeforeNavigate',
                    'Committed',
                    'Completed',
                    //'CreatedNavigationTarget', //Not supported by Firefox
                    'DOMContentLoaded',
                    'ErrorOccurred',
                    'HistoryStateUpdated',
                    'ReferenceFragmentUpdated'
                    //'TabReplaced' //Not supported by Firefox
                    ];


webNavEvents.forEach(function(navType){
    browser.webNavigation['on' + navType].addListener(function(type,details){
        console.log('\twebNavigation->' + type 
                    + ': tadId=' + details.tabId
                    + ':: url=' + details.url
                    + ((typeof details.transitionType === 'string') ? ':: transitionType='
                        + details.transitionType : '')
        );
    }.bind(undefined,navType));
});

这篇关于WebExtension:重新加载选项卡时反应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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