2010-08-12 11 views
8

Estoy desarrollando una extensión de Firefox y tienen el siguiente código:.onload llama varias veces a partir de extensión para 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'); 
    }; 
} 
  1. Al abrir la extensión (una barra lateral) y proceder a abrir una nueva pestaña dentro la ventana de Firefox, hay tres cuadros de alerta.
  2. Cuando actualizo una página, hay dos cuadros de alerta.
  3. Cuando una página termina de cargarse, solo hay un cuadro de alerta.
  4. Cuando cambio las pestañas, se activa una alerta.

Uso .onload en lugar de DOMContentLoaded o readystatechange, ya que tengo que esperar hasta que todos los demás javascript hayan terminado de cargarse en una página antes de ejecutar el mío.

¿Alguna idea de por qué se desencadenan múltiples eventos (y para las cosas que no deberían desencadenarse)?

SOLUCIÓN

Después de la sugerencia de MatrixFrog, aquí está la solución que vine a:

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'); 
    } 
} 
  1. aEvent.originalTarget.nodeName == '#document' comprueba que la página se ha cargado y no favicons.
  2. (aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec)) comprueba que el elemento que generó el evento es la página de la ficha, y no uno de sus IFRAMEs
  3. gBrowser.onload haría only fire para xul-image y no para #document así que fue reemplazado por gBrowser.addEventListener ("load", pageLoaded, true); !
  4. Si se quiere evitar disparar el caso de nuevas pestañas en blanco, asegúrese de gBrowser.currentURI.spec = "about: blank"
+1

La solución propuesta no se puede administrar cuando las páginas se cargan en diferentes pestañas de Firefox porque solo una pestaña (la pestaña enfocada) la condición aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec se evaluará como verdadera –

Respuesta

6

De https://developer.mozilla.org/en/Code_snippets/On_page_load

Firefox actual trunk nightlies activará la función onPageLoad no solo para documentos, sino también para xul:image s (favicons en tabbrowser). Si sólo desea manejar documentos, garantizar aEvent.originalTarget.nodeName == "#document"

Si sigue viendo eventos extraños 'carga' de la cocción, es posible que desee inspeccionar el destino del evento de averiguar lo que está siendo cargado, y el uso lógica similar para evitar llamar a la lógica de su extensión en ciertos casos específicos.

+0

dispara mucho menos, pero aún lo hace varias veces en algunas páginas. Supongo que esto se debe a iframes disparando un evento onload? Solo mirando cómo diferenciar una carga de iframe de la carga del documento y si hay una captura cuando la página y todos sus iframes se han cargado. – Ivan

+2

@Ivan, sí, probablemente sean iframes. Si no es un iframe, 'event.originalTarget.defaultView.frameElement' será nulo/indefinido. – MatrixFrog

+1

@MatrixFrog ¿Hay alguna otra manera de verificarlo? –

Cuestiones relacionadas