2009-04-15 15 views
72

Sto provando a rilevare quando un iframe e il suo contenuto sono stati caricati ma non hanno avuto molta fortuna. La mia applicazione accetta alcuni campi di testo nella finestra padre e aggiorna l'iframe per fornire un'anteprima liveRilevare quando il contenuto Iframe è stato caricato (Cross browser)

Ho iniziato con il seguente codice (YUI) per rilevare quando si verifica l'evento di caricamento iframe.

$E.on('preview-pane', 'load', function(){ 
    previewBody = $('preview-pane').contentWindow.document.getElementsByTagName('body')[0]; 
} 

'anteprima-pane' è l'ID del mio iframe e sto usando YUI per fissare il gestore di eventi. Tuttavia, il tentativo di accedere al corpo nella mia callback (su caricamento iframe) non funziona, penso perché l'iframe viene caricato prima che il gestore eventi sia pronto. Questo codice funziona se ritarda il caricamento dell'iframe facendo in modo che lo script php che lo genera dorma.

Fondamentalmente, sto chiedendo qual è l'approccio corretto tra i vari browser per rilevare quando l'iframe è stato caricato e il suo documento è pronto?

+1

Partendo con YUI è una cattiva idea (così come qualsiasi altra libreria JS). Perché? Perché semplicemente non puoi sapere che magia sta facendo quella libreria. Se non sono in grado di supportare "caricare" completamente, è meglio farlo da soli in un javascript chiaro e leggibile. – Christian

+2

Spesso è possibile leggere il codice sorgente della libreria @Christian. Trovo che questo di solito ti dia ottimi consigli su come farlo da solo, indipendentemente dal fatto che tu usi o meno la loro implementazione. – AJP

+0

@ AJP Hai frainteso il mio punto. Se stai facendo qualcosa di cui non sei sicuro, è meglio avere meno codice, quindi c'è meno spazio per errori. – Christian

risposta

58

per rilevare quando l'iframe è stato caricato e il documento è pronto?

È ideale se è possibile ottenere l'iframe per dirti da solo uno script all'interno del frame. Ad esempio, potrebbe chiamare direttamente una funzione genitore per dirgli che è pronta. L'assistenza è sempre necessaria con l'esecuzione di codice cross-frame poiché le cose possono accadere in un ordine che non ti aspetti. Un'altra alternativa è impostare 'var isready = true;' nel proprio ambito e avere lo sniff dello script genitore per 'contentWindow.isready' (e aggiungere il gestore onload se non lo è).

Se per qualche motivo non è pratico di avere il documento iframe co-operare, hai il tradizionale problema del carico-gara, vale a dire che, anche se gli elementi sono proprio accanto gli uni agli altri:

<img id="x" ... /> 
<script type="text/javascript"> 
    document.getElementById('x').onload= function() { 
     ... 
    }; 
</script> 

non è garantito che l'articolo non sia già stato caricato al momento dell'esecuzione dello script.

Le vie d'uscita di carico-razze sono:

  1. su IE, è possibile utilizzare la proprietà ‘readyState’ per vedere se qualcosa è già stato caricato;

  2. se l'articolo disponibile solo con JavaScript abilitato è accettabile, è possibile crearlo dinamicamente, impostando la funzione evento "onload" prima di impostare l'origine e l'accodamento alla pagina. In questo caso non può essere caricato prima che sia impostata la richiamata;

  3. la strada vecchia scuola di includere nel markup:

    <img onload="callback(this)" ... />

Inline 'onsomething' gestori in HTML sono quasi sempre la cosa sbagliata e da evitare, ma in questo caso a volte è l'opzione meno cattiva.

+0

Grazie. La mia soluzione controlla il readyState (se esiste), quindi gli elementi del corpo innerHTML length per vedere se è stato caricato. Altrimenti, allega il gestore eventi di caricamento. Sembra funzionare ok –

+7

-1 - gli eventi inline non sono "cattivi", è solo la moda attuale. In effetti, gli eventi in linea sono più facili da eseguire il debug e comprendere, a differenza delle loro controparti magiche (che, d'altra parte, sono più facili da allegare, impilare e utilizzare senza problemi). – Christian

+0

@Christian, gli eventi inline sono anche l'opzione migliore quando è necessario associare un evento a ogni elemento di un elenco molto lungo. Dato che stai già eseguendo il ciclo per creare l'elenco sul lato server, è molto più efficiente collegare anche l'evento inline. – haknick

43

Vedere post sul blog this. Usa jQuery, ma dovrebbe aiutarti anche se non lo stai usando.

Fondamentalmente si aggiunge questo al vostro document.ready()

$('iframe').load(function() { 
    RunAfterIFrameLoaded(); 
}); 
+0

Interessante, ma il problema che ho è con gli eventi di caricamento e i tempi. Sto ascoltando l'evento load come consigliato da quell'articolo. –

+0

ho provato questo con 'console.log'. viene registrato dopo che l'iframe è stato caricato. – shorif2000

1

Per coloro che utilizzano React, il rilevamento di un evento di caricamento iframe della stessa origine è semplice come impostare il listener di eventi sull'elemento iframe.

<iframe src={'path-to-iframe-source'} onLoad={this.loadListener} frameBorder={0} />

1

per chiunque utilizzi Ember, questo dovrebbe funzionare come previsto:

<iframe onLoad={{action 'actionName'}} frameborder='0' src={{iframeSrc}} /> 
Problemi correlati