WebExtension:重新加载选项卡时反应 [英] WebExtension: React when a a tab is reloaded
问题描述
我正在使用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屋!