问题在于 Firefox 扩展不能在任何特定窗口的上下文中运行。因此,他们通常没有定义 window 对象,或者如果您不熟悉编写扩展代码,它被定义为您不期望的东西。如果您从编写 JavaScript 以在 HTML 页面中使用的角度来处理此问题,则尤其如此。扩展在更大的上下文中运行,包括整个浏览器以及所有窗口和选项卡。因此,没有自动合适的窗口用作window 对象。在扩展的上下文中,每个 HTML 页面只是整体的一部分。
您可以通过使用nsIWindowMediator 获取每个主浏览器窗口。以下函数 from MDN 将为每个打开的窗口运行一次您传递给它的函数:
Components.utils.import("resource://gre/modules/Services.jsm");
function forEachOpenWindow(todo) // Apply a function to all open browser windows
{
var windows = Services.wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements())
todo(windows.getNext().QueryInterface(Components.interfaces.nsIDOMWindow));
}
您通常希望找到用户最近访问的浏览器/标签的window。以下代码将定义 window 变量并将其设置为最近使用的浏览器/选项卡。它可以在附加 SDK 中工作,也可以在覆盖/引导扩展中工作,具体取决于您取消注释的部分。
有关在 Firefox 扩展程序中使用 Windows 的更多信息,您应该查看Working with windows in chrome code,也许还有Tabbed browser。
if (window === null || typeof window !== "object") {
//If you do not already have a window reference, you need to obtain one:
// Add a "/" to un-comment the code appropriate for your add-on type.
/* Add-on SDK:
var window = require('sdk/window/utils').getMostRecentBrowserWindow();
//*/
/* Overlay and bootstrap (from almost any context/scope):
var window=Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator)
.getMostRecentWindow("navigator:browser");
//*/
}
交替使用Services.jsm访问nsIWindowMediator:
/* Overlay and bootstrap:
Components.utils.import("resource://gre/modules/Services.jsm");
//*/
if (window === null || typeof window !== "object") {
//If you do not already have a window reference, you need to obtain one:
// Add a "/" to un-comment the code appropriate for your add-on type.
/* Add-on SDK:
var window = require('sdk/window/utils').getMostRecentBrowserWindow();
//*/
/* Overlay and bootstrap (from almost any context/scope):
var window = Services.wm.getMostRecentWindow("navigator:browser");
//*/
}
以下是一些可能有用的附加变量,具体取决于您正在执行的操作:
if (typeof document === "undefined") {
//If there is no document defined, get it
var document = window.content.document;
}
if (typeof gBrowser === "undefined") {
//If there is no gBrowser defined, get it
var gBrowser = window.gBrowser;
}
var tab = gBrowser.selectedTab;
var browserForTab = gBrowser.getBrowserForTab( tab );
var notificationBox = gBrowser.getNotificationBox( browserForTab );
var ownerDocument = gBrowser.ownerDocument;
注意:此答案的内容主要取自我的答案 here 和 here,但基于 MDN 的代码。对我来说,遍历所有打开的浏览器窗口的代码起源于 original article MDN 文章 How to convert an overlay extension to restartless 所依据的。