Dlaczego google.load powoduje, że moja strona jest pusta?

103

Cóż, wygląda to dziwnie, ale nie jestem w stanie znaleźć rozwiązania.

Dlaczego na świecie takie skrzypce http://jsfiddle.net/carlesso/PKkFf/ pokazują zawartość strony, a kiedy pojawia się google.load, strona staje się pusta?

Działa dobrze, jeśli plik google.load jest wykonywany natychmiast, ale opóźnienie go w ogóle nie działa.

Oto źródło strony dla bardziej leniwych (lub mądrzejszych) z was:

<!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
źródło
1
miłe pytanie, oto link: friendlybit.com/js/lazy-loading-asyncronous-javascript (innymi słowy: nie ma jeszcze pojęcia)
mindandmedia
Zauważyłem, że document.write ('cokolwiek') wyczyści również poprzedni kod HTML, może dokument nie działa poprawnie w kontekście ustawionego limitu czasu?
mindandmedia

Odpowiedzi:

109

Wygląda na to, że google.load dodaje skrypt do strony za pomocą funkcji document.write (), która w przypadku użycia po załadowaniu strony usuwa kod HTML.

To wyjaśnia bardziej szczegółowo: http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/e07c2606498094e6

Korzystając z jednego z pomysłów, możesz użyć wywołania zwrotnego dla obciążenia, aby wymusić użycie dołączania zamiast doc.write:

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

Pokazuje to 2-sekundowe oczekiwanie z oknem opóźnionego alertu

fala
źródło
Nie chcę, aby okno alertu było wyświetlane. Czy jest w pobliżu jakaś praca?
Shoib Mohammed A
4
Alert był tylko przykładowym fragmentem kodu. To może być wszystko.
fala z
To jest świetne. Jedyną rzeczą, którą zmieniłem, aby działała zgodnie z oczekiwaniami, było wywołanie funkcji drawChart zamiast funkcji ostrzegania.
chiurox
Samo dodanie pustego parametru wywołania zwrotnego naprawiło to za mnie.
Adam B
32

Musisz tylko zdefiniować callback, a nie wyczyści strony (być może starsze wersje google.load () tak, ale najwyraźniej nowe nie są używane z callbackiem). Oto uproszczony przykład, kiedy ładuję bibliotekę „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!
        }
    } )
}

Gdy robię to bez wywołania zwrotnego (), nadal otrzymuję pustą stronę - ale z wywołaniem zwrotnym jest to dla mnie naprawione.

Katai
źródło
5

Uwaga: Poniższe wskazówki są przydatne, aby uniknąć opóźnień czasowych - są w samą porę. Przykład może być używany ogólnie przez wszystkie skrypty (które go potrzebują), ale był szczególnie używany z Greasemonkey. Jako przykład wykorzystuje również interfejs API wykresów Google, ale to rozwiązanie wykracza poza inne interfejsy API Google i może być używane w dowolnym miejscu, w którym trzeba czekać na załadowanie skryptu.

Używanie google.load z wywołaniem zwrotnym nie rozwiązało problemu podczas używania Greasemonkey do dodawania wykresu Google. W trakcie procesu (Greasemonkey wstrzyknięty na stronę), dodawany jest węzeł skryptowy www.google.com/jsapi. Po dodaniu tego elementu dla javascript jsapi Google, wstrzykiwany (lub stronicowy) skrypt jest gotowy do użycia polecenia google.load (które należy załadować w dodanym węźle), ale ten skrypt jsapi jeszcze się nie załadował. Ustawienie limitu czasu zadziałało, ale limit czasu był jedynie obejściem wyścigu czasowego ładowania skryptu Google jsapi ze skryptem injected / page. Poruszanie się po miejscu, w którym skrypt wykonuje plik google.load (i prawdopodobnie google.setOnLoadCallback), może wpłynąć na sytuację wyścigu czasowego. Poniższe oferuje rozwiązanie, które czeka na załadowanie elementu skryptu Google przed wywołaniem google.load. Oto przykład:

// ********* 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";
codeaperature
źródło
2

Nie musisz ustawiać limitu czasu. Jest inny sposób:

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

Wyjaśnienie:

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

zostanie wykonany po pomyślnym załadowaniu skryptu JSAPI, a następnie alert () zostanie wykonany po pomyślnym załadowaniu google.load ()

Kamil Mierzyński
źródło
2

Napotkałem ten problem podczas próby przeniesienia google.load(…)wewnątrz $(document).ready(…)opakowania jQuery . Przeniesienie google.load(…) tyłu poza gotową funkcję tak, aby wykonywała się natychmiast, rozwiązało problem.

Na przykład to nie działa:

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

Ale to robi:

google.load('visualization', '1', {packages: ['corechart']});
$(document).ready(function() {
    // …
});
Quinn Comendant
źródło