¿Por qué google.load hace que mi página quede en blanco?

103

Bueno, esto parece extraño pero no puedo encontrar una solución.

¿Por qué demonios este violín http://jsfiddle.net/carlesso/PKkFf/ muestra el contenido de la página y, luego, cuando ocurre google.load, la página se queda en blanco?

Funciona bien si google.load se realiza inmediatamente, pero retrasarlo no funciona en absoluto.

Aquí la fuente de la página para el más perezoso (o más inteligente) de ustedes:

<!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>​
Enrico Carlesso
fuente
1
buena pregunta, aquí hay un enlace: friendlybit.com/js/lazy-loading-asyncronous-javascript (en otras palabras: aún no
tengo
Me di cuenta de que document.write ('cualquier cosa') también borrará el html anterior, ¿tal vez el documento está fuera de control en el contexto de settimeout?
mindandmedia

Respuestas:

109

Parece que google.load está agregando el script a la página usando un document.write (), que si se usa después de que se cargue la página, borra el html.

Esto explica más en profundidad: http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/e07c2606498094e6

Usando una de las ideas, podría usar una devolución de llamada para la carga para forzarla a usar append en lugar de doc.write:

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

Esto demuestra la espera de 2 segundos con la ventana de alerta retrasada

ola
fuente
No quiero que se muestre la ventana de alerta, ¿hay algún trabajo alrededor para hacer eso?
Shoib Mohammed A
4
La alerta fue solo un fragmento de código de ejemplo. Puede ser cualquier cosa.
ola
Esto es genial. Lo único que cambié para que funcione como esperaba fue llamar a la función drawChart en lugar de la función de alerta.
chiurox
Simplemente agregando un parámetro de devolución de llamada vacío lo solucionó para mí.
Adam B
32

Solo tiene que definir una devolución de llamada, y no borrará la página (tal vez las versiones anteriores de google.load () lo hicieron, pero aparentemente las nuevas no lo hacen si se usan con la devolución de llamada). Aquí un ejemplo simplificado cuando estoy cargando la biblioteca "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!
        }
    } )
}

Cuando lo hago sin devolución de llamada (), también obtengo la página en blanco, pero con la devolución de llamada, se solucionó para mí.

Katai
fuente
5

Nota: Lo siguiente es bueno para evitar un retraso de tiempo: es justo a tiempo. El ejemplo puede ser utilizado generalmente por todos los scripts (que lo necesiten), pero se utilizó especialmente con Greasemonkey. También usa la API de gráficos de Google como ejemplo, pero esta solución va más allá de otras API de Google y se puede usar en cualquier lugar donde necesite esperar a que se cargue un script.

Usar google.load con una devolución de llamada no resolvió el problema al usar Greasemonkey para agregar un gráfico de Google. En el proceso (Greasemonkey inyectado en la página), se agrega el nodo de secuencia de comandos www.google.com/jsapi. Después de agregar este elemento para el javascript jsapi de Google, el script inyectado (o página) está listo para usar el comando google.load (que debe cargarse en el nodo agregado), pero este script jsapi aún no se cargó. La configuración del tiempo de espera funcionó, pero el tiempo de espera fue simplemente una solución para la carrera de sincronización de carga del script jsapi de Google con el script inyectado / page. Moverse por donde un script ejecuta google.load (y posiblemente google.setOnLoadCallback) puede afectar la situación de la carrera cronometrada. A continuación, se ofrece una solución que espera a que se cargue el elemento de secuencia de comandos de Google antes de llamar a google.load. Aquí hay un ejemplo:

// ********* 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";
código de funcionamiento
fuente
2

No es necesario configurar el tiempo de espera. Hay otra forma:

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

Explicación:

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

se ejecutará después de cargar correctamente el script JSAPI, luego alert () se ejecutará después de que google.load ()

Kamil Mierzyński
fuente
2

Encontré este problema al intentar mover un contenedor google.load(…)dentro de jQuery $(document).ready(…). Mover la parte google.load(…) posterior fuera de la función lista para que se ejecute inmediatamente resolvió el problema.

Por ejemplo, esto no funciona:

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

Pero esto hace:

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