2012-03-01 12 views
102

Bene, questo sembra strano ma non sono in grado di trovare una soluzione.Perché google.load causa la pagina vuota?

Perché nel mondo questo violino http://jsfiddle.net/carlesso/PKkFf/ mostra il contenuto della pagina e, quindi, quando si verifica google.load, la pagina diventa vuota?

Funziona bene se il google.load viene eseguito immediatamente, ma il suo ritardo non funziona affatto.

Ecco il sorgente della pagina per il più pigri (o intelligente) di voi:

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
    <title>Ciao</title> 
    <script type="text/javascript" src="https://www.google.com/jsapi"></script> 
    </head> 
    <body> 
    <h1>Test</h1> 
    <div id="quicivanno"> 
     <p>ciao</p> 
    </div> 
    </body> 
    <script type="text/javascript"> 
     setTimeout(function() {google.load('visualization', '1.0', {'packages':['corechart']});}, 2000); 
    </script> 
</html>​ 
+1

bella domanda, ecco un link: http://friendlybit.com/js/lazy-loading -asyncronous-javascript/(in altre parole: nessun indizio) – mindandmedia

+0

ho notato che document.write ('qualsiasi cosa') cancellerà anche l'html precedente, forse il documento è fuori questione nel contesto di settimeout? – mindandmedia

risposta

106

Sembra google.load sta aggiungendo lo script per la pagina utilizzando un document.write(), che se preso dopo il carica la pagina, cancella l'html.

Questo spiega più in profondità: http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/e07c2606498094e6

Usando una delle idee, è possibile utilizzare un callback per il carico di forzarlo usare accodamento piuttosto che doc.write:

setTimeout(function(){google.load('visualization', '1', {'callback':'alert("2 sec wait")', 'packages':['corechart']})}, 2000); 

Questo dimostra l'attesa di 2 secondi con la finestra di avviso ritardata

+0

Non desidero che venga visualizzata la finestra di avviso. C'è qualche lavoro in giro per farlo? –

+4

L'avviso era solo un esempio di snippet di codice. Può essere qualsiasi cosa. – wave

+0

Questo è fantastico. L'unica cosa che ho modificato per funzionare come mi aspettavo era chiamare la funzione drawChart invece della funzione di avviso. – chiurox

5

Nota: quanto segue è un buon modo per evitare ritardi - è appena in tempo. L'esempio può essere usato generalmente da tutti gli script (che ne hanno bisogno), ma è stato particolarmente utilizzato con Greasemonkey. Ad esempio, utilizza l'API del grafico di Google, ma questa soluzione va oltre alle altre API di Google e può essere utilizzata ovunque sia necessario attendere il caricamento di uno script.

L'utilizzo di google.load con un callback non ha risolto il problema quando si utilizza Greasemonkey per aggiungere un grafico di Google. Nel processo (Greasemonkey immesso nella pagina), viene aggiunto il nodo di script www.google.com/jsapi. Dopo aver aggiunto questo elemento per jsapi javascript di Google, lo script iniettato (o pagina) è pronto per utilizzare il comando google.load (che deve essere caricato nel nodo aggiunto), ma questo script jsapi non è stato ancora caricato. L'impostazione del timeout ha funzionato, ma il timeout era semplicemente una soluzione alternativa per la corsa dei tempi del carico di script di jsapi di Google con lo script di input/page. Spostarsi dove uno script esegue il google.load (ed eventualmente google.setOnLoadCallback) può influenzare la situazione della corsa a tempo. Quanto segue offre una soluzione che attende il caricamento dell'elemento script di google prima di chiamare google.load. Ecco un esempio:

// ********* INJECTED SCRIPT *********// 
// add element 
var gscript = document.createElement('script'); 
gscript.setAttribute("type", "application/javascript"); 
gscript.setAttribute("id", "XX-GMPlusGoogle-XX"); 
document.body.appendChild(gscript); 

// event listener setup  
gscript.addEventListener("load",  
    function changeCB(params) { 
     gscript.removeEventListener("load", changeCB); 
     google.load("visualization", "1", {packages:["corechart"], "callback": 
      function drawChart() { 
       var data; 
       // set the durationChart data (not in example) 
       data = new google.visualization.arrayToDataTable(durationChart); 

       var options = { 
        title:"Chart Title", 
        legend: {position:"none"}, 
        backgroundColor:"white", 
        colors:["white","Blue"], 
        width: window.innerWidth || document.body.clientWidth, 
        height: window.innerHeight || document.body.clientHeight, 
        vAxis: {title: "Durations", baselineColor: "black", textStyle:{fontSize:12}}, 
        hAxis: {title: "Days Since First Instance"}, 
        height: ((cnt > 5)? cnt * 50 : 300), 
        isStacked: true 
       }; // options 


       // put chart into your div element 
       var chart = new google.visualization.BarChart(document.getElementById('XX-ChartDiv-XX')); 
       chart.draw(data, options); 
      } // drawChart function 
     }); //packages within google.load & google load 
    } // callback changeCB 
); 

// can use SSL as "https://www.google.com/jsapi"; 
gscript.src = "http://www.google.com/jsapi"; 
32

Non vi resta che definire una callback, e non sarà chiaro nella pagina (forse le vecchie versioni di google.load() ha fatto, ma a quanto pare quelli nuovi non lo fanno, se utilizzato con richiama). Ecco un esempio semplificato quando sto caricando la lib "google.charts":

if(google) { 
    google.load('visualization', '1.0', { 
     packages: ['corechart'], 
     callback: function() { 
      // do stuff, if you wan't - it doesn't matter, because the page isn't blank! 
     } 
    }) 
} 

Quando farlo whitout callback(), ho ancora ottenere la pagina bianca troppo - ma con callback, è fissato per me.

+2

Questo funziona anche per me. Ma perché funziona? –

2

Non è necessario impostare il timeout. C'è un altro modo:

$.getScript("https://www.google.com/jsapi", function() { 
    google.load('visualization', '1', { 'callback': 'alert()', 'packages': ['corechart'] }); 
}); 

Spiegazione:

function() { 
    google.load('visualization', '1', { 'callback': 'alert()', 'packages': ['corechart'] }); 
} 

viene eseguito dopo il successo script di caricamento JSAPI, quindi alert() sarà eseguito dopo che Google successo.load()

2

Ho riscontrato questo problema durante il tentativo di spostare un google.load(…) all'interno di un wrapper jQuery $(document).ready(…). Lo spostamento del google.load(…) al di fuori della funzione ready in modo che venga eseguito immediatamente ha risolto il problema.

Ad esempio, questa non funziona:

$(document).ready(function() { 
    google.load('visualization', '1', {packages: ['corechart']}); 
}); 

Ma questo fa:

google.load('visualization', '1', {packages: ['corechart']}); 
$(document).ready(function() { 
    // … 
}); 
Problemi correlati