我在插件上工作,观察所有的http请求并填充与每个标签对应的一些信息。我想清除我关闭的选项卡的数据。但是,我无法以更清洁/更健全的方式获得标识选项。
所以我有contentWindow
(LoadContext - > associatedWindow)请求,以及该内容窗口的browser
(用于选项卡)。
browser.addEventListener
,我将不得不听DOMNodeRemoved
事件 - deprecated as per MDN(而应该使用变异观察者)。此外,当弹出窗口关闭时,我不会收到事件。contentWindow.addEventListener
并查找unload
事件,则结果非常难以预测。有时候,我根本没有参加活动。 tab
获取此gBrowser.tabs
元素并收听TabClose
事件,我可以获取该标签的所有关闭事件。但话说回来,它不会通知任何弹出窗口关闭(虽然我为弹出窗口获得了tab
元素)那么知道任何标签/弹出窗口关闭的最简单/最简洁的方法是什么?我不使用插件SDK,顺便说一句。
编辑:寻找更简单,有效的案例解决方案。即。我收到关闭事件的通知,无论是标签还是弹出窗口(或任何其他类型的窗口,如果它们存在!)。我相信这可能是可能的,因为我持有一个包含DOM窗口的浏览器元素,并在关闭时删除(卸载)DOM。
EDIT-2:意识到所有问题都是由于一件事:当最后一个标签关闭时(这是窗口关闭),Firefox没有TabClose
事件。如果我们收到关闭窗口时关闭的标签的通知,那么生活会容易得多。除了TabClose
监听器之外,我还会采用@ Noitidart解决方案的修改版本 - 拥有一个单独的窗口监听器。并找到其中的tab
元素并进行清理。叹!
将在此进行更多搜索,并查看是否符合错误/增强的条件。
感谢@Noitidart和@Blargh的建议。
答案 0 :(得分:2)
我说要保留对标签的引用。这就是我在插件MouseControl和WorkspaceHopper中的表现。
所以请检查:
if (tab.parentNode) {
}
尝试捕获,如果它捕获,那么tab显然不存在。
但是对于tabClose你也可以使用tabclose事件和窗口弹出窗口,使用windowsMediator列表器并听取onWindowClose
var windowListener = {
//DO NOT EDIT HERE
onOpenWindow: function (aXULWindow) {
// Wait for the window to finish loading
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
aDOMWindow.addEventListener('load', function () {
aDOMWindow.removeEventListener('load', arguments.callee, false);
windowListener.loadIntoWindow(aDOMWindow);
}, false);
},
onCloseWindow: function (aXULWindow) {},
onWindowTitleChange: function (aXULWindow, aNewTitle) {},
register: function () {
// Load into any existing windows
let DOMWindows = Services.wm.getEnumerator(null);
while (DOMWindows.hasMoreElements()) {
let aDOMWindow = DOMWindows.getNext();
windowListener.loadIntoWindow(aDOMWindow);
}
// Listen to new windows
Services.wm.addListener(windowListener);
},
unregister: function () {
// Unload from any existing windows
let DOMWindows = Services.wm.getEnumerator(null);
while (DOMWindows.hasMoreElements()) {
let aDOMWindow = DOMWindows.getNext();
windowListener.unloadFromWindow(aDOMWindow);
}
//Stop listening so future added windows dont get this attached
Services.wm.removeListener(windowListener);
},
//END - DO NOT EDIT HERE
loadIntoWindow: function (aDOMWindow) {
if (!aDOMWindow) {
return;
}
//do stuff here
},
unloadFromWindow: function (aDOMWindow) {
if (!aDOMWindow) {
return;
}
//do stuff here
}
};
答案 1 :(得分:2)
这是@Noitidart答案的修改版本。我在browser
上使用expando属性(例如:_myextensionTabId
)来索引我的缓存数组。
var WindowListener = {
/* Same as @Noitidart's listener */
onOpenWindow : function(xulWindow) {
/* Get DOM window, call other window specific modules init */
myExtension.initWindow(domWindow);
myHttpObserver.initWindow(domWindow);
},
onCloseWindow: function(xulWindow) {
/* Get DOM window, call other window specific modules uninit */
myExtension.uninitWindow(domWindow);
myHttpObserver.uninitWindow(domWindow);
},
};
var myHttpObserver = {
..
initWindow: function(window) {
window.gBrowser.tabContainer
.addEventListener('TabClose', tabClosed, false);
},
uninitWindow: function(window) {
dump ("Uninit window http observer\n");
window.gBrowser.tabContainer
.removeEventListener('TabClose', tabClosed);
for (var browser of window.gBrowser.browsers) {
if (browser._myextensionTabId) {
// Do any cleanup.
}
}
},
..
/* Other http observer stuff, methods that sets the expando property etc. */
};
function tabClosed(e) {
var browser = Services.wm.getMostRecentWindow("navigator:browser")
.gBrowser.getBrowserForTab(e.target);
dump("Tab closed. \n");
if (browser._myextensionTabId) {
dump("My extension tab id : " + browser._myextensionTabId);
// Do any cleanup
}
}
答案 2 :(得分:1)
对于一个解决方案拟合选项卡和窗口,您可以尝试窗口观察者: https://developer.mozilla.org/en-US/docs/Observer_Notifications#Windows
可能想要使用outer-window-destroyed
观察者,我认为标签中的每个浏览器元素都是一个外窗口。我不确定。它可能会在每次文档更改时触发,因此您必须QI并获取选项卡并检查其是关闭/关闭还是仍然打开。
尝试一下,与我们分享你学到的东西,我很感兴趣。在收盘时我认为它会被摧毁。