.onload 从 Firefox 扩展调用多次
我正在开发一个 Firefox 扩展程序,并具有以下代码:
function initialize() {
// For accessing browser window from sidebar code.
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
var gBrowser = mainWindow.gBrowser;
gBrowser.onload = function() {
alert('loaded');
};
}
- 当我打开扩展程序(侧边栏)并继续在 Firefox 窗口中打开新选项卡时,会出现三个警告框。
- 当我刷新页面时,有两个警告框。
- 当页面加载完成时,只有一个警告框。
- 当我更改选项卡时,会触发警报。
我使用 .onload 而不是 DOMContentLoaded 或 Readystatechange,因为我需要等到所有其他 javascript 完成在页面上的加载后才能运行我的。
关于为什么触发多个事件(以及不应该触发事件的事情)有什么想法吗?
解决方案
根据 MatrixFrog 的建议,这是我得出的解决方案:
function initialize() {
// For accessing browser window from sidebar code.
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
var gBrowser = mainWindow.gBrowser;
if (gBrowser.addEventListener) {
gBrowser.addEventListener("load",pageLoaded,true);
}
}
function pageLoaded(aEvent) {
if ((aEvent.originalTarget.nodeName == '#document') &&
(aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec))
{
alert('loaded');
}
}
- aEvent.originalTarget.nodeName == '#document' 检查页面是否已加载,而不是图标。
- (aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec)) 检查触发事件的元素是否为选项卡中的页面,并且其 IFRAME 之一
- gBrowser.onload 不会仅针对 xul-image 触发不适用于#document,因此它被替换为 gBrowser.addEventListener("load",pageLoaded,true);
- 如果您想避免触发新空白选项卡的事件,请确保 gBrowser.currentURI.spec != "about:blank"
I'm developing a Firefox extension and have the following code:
function initialize() {
// For accessing browser window from sidebar code.
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
var gBrowser = mainWindow.gBrowser;
gBrowser.onload = function() {
alert('loaded');
};
}
- When I open the extension (a sidebar) and proceed to open a new tab within the Firefox window, there are three alert boxes.
- When I refresh a page, there are two alert boxes.
- When a page finishes loading, there is only one alert box.
- When I change tabs, an alert is fired.
I use .onload rather than DOMContentLoaded or readystatechange as I need to wait until all other javascript has finished loading on a page before I run mine.
Any ideas as to why multiple events are being triggered (and for things that the event shouldn't be triggered for)?
SOLUTION
Following from MatrixFrog's suggestion, here is the solution I came to:
function initialize() {
// For accessing browser window from sidebar code.
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
var gBrowser = mainWindow.gBrowser;
if (gBrowser.addEventListener) {
gBrowser.addEventListener("load",pageLoaded,true);
}
}
function pageLoaded(aEvent) {
if ((aEvent.originalTarget.nodeName == '#document') &&
(aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec))
{
alert('loaded');
}
}
- aEvent.originalTarget.nodeName == '#document' checks that the page is loaded and not favicons.
- (aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec)) checks that the element that fired the event is the page in the tab, and not one of its IFRAMEs
- gBrowser.onload would only fire for xul-image and not for #document so it was replaced with gBrowser.addEventListener("load",pageLoaded,true);
- If you want to avoid firing the event for new blank tabs, make sure gBrowser.currentURI.spec != "about:blank"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
来自 https://developer.mozilla.org/en/Code_snippets/On_page_load
如果您仍然看到无关的“load”事件触发,您可能需要检查事件目标来确定找出正在加载的内容,并使用类似的逻辑来避免在某些特定情况下调用扩展的逻辑。
From https://developer.mozilla.org/en/Code_snippets/On_page_load
If you're still seeing extraneous 'load' events firing, you may want to inspect the event target to figure out what's being loaded, and use similar logic to avoid calling your extension's logic in certain specific cases.