我正在开发一个 Firefox WebExtension,它有一个弹出窗口并用于chrome.storage.local
存储状态。到目前为止,我已经使用选项卡 ID 存储特定选项卡的数据。
如果重新加载当前选项卡,我想重新初始化本地存储。这是因为扩展可能对 DOM 进行了一些更改,如果重新加载选项卡,这些更改将会丢失;因此它存储的状态是不正确的。
从弹出窗口调用初始 JavaScript 代码。
重新加载页面时如何运行一些代码?
谢谢
我正在开发一个 Firefox WebExtension,它有一个弹出窗口并用于chrome.storage.local
存储状态。到目前为止,我已经使用选项卡 ID 存储特定选项卡的数据。
如果重新加载当前选项卡,我想重新初始化本地存储。这是因为扩展可能对 DOM 进行了一些更改,如果重新加载选项卡,这些更改将会丢失;因此它存储的状态是不正确的。
从弹出窗口调用初始 JavaScript 代码。
重新加载页面时如何运行一些代码?
谢谢
如果没有您提供更多关于您想要做什么的信息,就很难确定执行此操作的最佳方法。特别是,很难确切地知道您希望对哪些情况做出反应。
看起来您可以使用tabs.onUpdated
事件侦听器。虽然这比您实际想要的更频繁,但它确实会在重新加载页面时触发。
completedLoadingURLInTab()
下面是在 URL 已加载或在页面上重新加载时调用函数的代码。我留下了一堆console.log()
电话作为我通常会删除的评论。它们可以取消注释以在事件触发时一直显示在控制台中。这对于准确确定从事件接收到的数据的内容以及在各种页面导航期间触发的事件序列很有用。
注1:我发现changeInfo
对象在某些情况下可能无效。有必要查看一个属性是否存在hasOwnProperty()
,然后从tabs.Tab
传递给事件处理程序的对象中获取值。
注2:需要manifest.json中的tabs
权限。
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
});
加载加载项、打开一个新选项卡并进行一些导航(包括一些页面重新加载),控制台中的输出可能如下所示:
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
事件直接为您提供有关 Web 导航的信息。他们可能会为您提供比tabs.onUpdated
.
如果您使用webNavigation
事件,则需要进行试验以查看针对您所关注的情况触发的事件组合。这很可能是Completed
和/或ReferenceFragmentUpdated
。
因此,您可以了解这些事件何时触发,以下代码会将所有webNavigation
事件记录到控制台:
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));
});