Почему из-за google.load моя страница становится пустой?

103

Что ж, это выглядит странно, но я не могу найти решение.

Почему эта скрипка http://jsfiddle.net/carlesso/PKkFf/ показывает содержимое страницы, а затем, когда происходит google.load, страница становится пустой?

Это хорошо работает, если google.load выполняется немедленно, но отложить его не получится.

Вот источник страницы для более ленивых (или более умных) из вас:

<!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
хороший вопрос, вот ссылка: friendlybit.com/js/lazy-loading-asyncronous-javascript (другими словами: пока нет подсказки)
mindandmedia 01
Я заметил, что document.write ('something') также очистит предыдущий html, возможно, документ не в порядке в контексте settimeout?
mindandmedia 01

Ответы:

109

Похоже, google.load добавляет скрипт на страницу с помощью document.write (), который, если он используется после загрузки страницы, стирает HTML.

Это объясняет более подробно: http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/e07c2606498094e6

Используя одну из идей, вы можете использовать обратный вызов для загрузки, чтобы заставить ее использовать append, а не doc.write:

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

Это демонстрирует 2-секундное ожидание с окном отложенного предупреждения.

волна
источник
Я не хочу, чтобы отображалось окно с предупреждением, есть ли для этого какие-то возможности?
Shoib Mohammed A
4
Предупреждение было всего лишь примером фрагмента кода. Это может быть что угодно.
волна
Это круто. Единственное, что я изменил, чтобы работать так, как я ожидал, - это вызвать функцию drawChart вместо функции предупреждения.
chiurox
Просто добавление пустого параметра обратного вызова исправило это для меня.
Adam B
32

Вам просто нужно определить обратный вызов, и он не очистит страницу (возможно, старые версии google.load () сделали это, но, очевидно, новые не работают, если используются с обратным вызовом). Вот упрощенный пример, когда я загружаю библиотеку "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!
        }
    } )
}

Когда я делаю это без callback (), я все равно получаю пустую страницу, но с обратным вызовом это исправлено для меня.

Катай
источник
5

Примечание. Следующее помогает избежать задержки по времени - это как раз вовремя. Этот пример может использоваться в целом всеми скриптами (в которых он нужен), но особенно использовался с Greasemonkey. Он также использует API диаграмм Google в качестве примера, но это решение выходит за рамки других API Google и может использоваться везде, где вам нужно дождаться загрузки скрипта.

Использование google.load с обратным вызовом не решило проблему при использовании Greasemonkey для добавления диаграммы Google. В процессе (Greasemonkey вводится на страницу) добавляется узел сценария www.google.com/jsapi. После добавления этого элемента для jsapi javascript Google внедренный сценарий (или страница) готов к использованию команды google.load (которую необходимо загрузить в добавленный узел), но этот сценарий jsapi еще не загрузился. Установка тайм-аута сработала, но тайм-аут был просто обходным путем для гонки времени загрузки скрипта Google jsapi с внедренным скриптом / page. Перемещение в том месте, где скрипт выполняет google.load (и, возможно, google.setOnLoadCallback), может повлиять на ситуацию гонки по времени. Ниже предлагается решение, которое ожидает загрузки элемента скрипта Google перед вызовом google.load. Вот пример:

// ********* 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";
кодовая температура
источник
2

Вам не нужно устанавливать тайм-аут. Есть еще один способ:

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

Пояснение:

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

будет выполняться после успешной загрузки JSAPI-скрипта, затем alert () будет выполнен после успешной загрузки google.load ()

Камил Межинский
источник
2

Я столкнулся с этой проблемой при попытке переместить google.load(…)внутри $(document).ready(…)оболочки jQuery . Перемещение google.load(…) назад за пределы функции готовности, чтобы она выполнялась немедленно, решила проблему.

Например, это не работает:

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

Но это действительно так:

google.load('visualization', '1', {packages: ['corechart']});
$(document).ready(function() {
    // …
});
Куинн Комендант
источник