2010-08-12 16 views
8

sto sviluppando un'estensione per Firefox e hanno il seguente codice:.onload chiamato più volte da estensione per 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. Quando apro l'estensione (una barra laterale) e procedere ad aprire una nuova scheda all'interno la finestra di Firefox, ci sono tre caselle di avviso.
  2. Quando si aggiorna una pagina, ci sono due caselle di avviso.
  3. Al termine del caricamento di una pagina, è presente una sola casella di avviso.
  4. Quando cambio scheda, viene generato un avviso.

Io uso .carico piuttosto che DOMContentLoaded o readystatechange poiché devo attendere che tutti gli altri javascript abbiano completato il caricamento su una pagina prima di eseguire il mio.

Qualche idea sul motivo per cui vengono attivati ​​più eventi (e per cose per cui l'evento non deve essere attivato)?

SOLUZIONE

seguito dal suggerimento di MatrixFrog, ecco la soluzione sono venuto 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' verifica che la pagina viene caricata e non favicon.
  2. (aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec)) Verifica che l'elemento che ha generato l'evento è la pagina nella scheda, e non uno dei suoi IFRAME
  3. gBrowser.onload sarebbe solo fire per xul-image e non per #document quindi è stato sostituito con gBrowser.addEventListener ("load", pageLoaded, true); !
  4. Se si vuole evitare di generare l'evento per le nuove schede vuote, assicurarsi gBrowser.currentURI.spec = "about: blank"
+1

La soluzione proposta non può essere gestita quando le pagine vengono caricate su diverse schede firefox solo per una scheda (la scheda focalizzata) la condizione aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec verrà valutata come vera –

risposta

6

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

Firefox corrente Nightbox tronco sparerà la funzione onPageLoad per non solo i documenti, ma xul:image s (favicon in tabbrowser). Se si desidera solo per gestire i documenti, garantire aEvent.originalTarget.nodeName == "#document"

Se stai ancora vedendo eventi estranei 'carico' la cottura, si consiglia di ispezionare il target dell'evento per capire ciò che è stato caricato, e l'uso logica simile per evitare di chiamare la logica dell'estensione in alcuni casi specifici.

+0

spara molto meno, ma fa ancora più volte su alcune pagine. Suppongo che ciò sia dovuto agli iframe che attivano un evento onload? Solo esaminando come distinguere un carico iframe dal carico del documento e se c'è di catturare quando la pagina e tutti i suoi iframe sono stati caricati. – Ivan

+2

@ Ivan, sì, probabilmente sono iframe. Se non è un iframe allora 'event.originalTarget.defaultView.frameElement' sarà nullo/indefinito. – MatrixFrog

+1

@ MatrixFrog C'è un altro modo per controllarlo? –

Problemi correlati