.onload从Firefox扩展中多次调用

Iva*_*van 9 javascript firefox-addon onload dom-events

我正在开发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');
    };
}
Run Code Online (Sandbox Code Playgroud)
  1. 当我打开扩展程序(侧边栏)并继续在Firefox窗口中打开一个新选项卡时,有三个警告框.
  2. 刷新页面时,有两个警告框.
  3. 页面完成加载后,只有一个警告框.
  4. 当我更改标签时,会触发警报.

我使用.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');
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. aEvent.originalTarget.nodeName =='#document'检查页面是否已加载而不是favicons.
  2. (aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec))检查触发事件的元素是选项卡中的页面,而不是其中一个IFRAME
  3. gBrowser.onload只会触发xul-image而不是#document,因此它被替换为gBrowser.addEventListener("load",pageLoaded,true);
  4. 如果要避免为新的空白选项卡触发事件,请确保gBrowser.currentURI.spec!="about:blank"

Mat*_*rog 7

来自https://developer.mozilla.org/en/Code_snippets/On_page_load

当前的Firefox trunk night会不仅触发onPageLoad函数,而且还xul:image触发s(tabbrowser中的favicons).如果您只想处理文档,请确保aEvent.originalTarget.nodeName == "#document"

如果您仍然看到无关的"加载"事件触发,您可能需要检查事件目标以确定正在加载的内容,并使用类似的逻辑来避免在某些特定情况下调用扩展的逻辑.

  • @Ivan,是的,可能是iframe.如果它不是iframe,那么`event.originalTarget.defaultView.frameElement`将为null/undefined. (2认同)