Чому 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

Я помітив, що document.write ('що-небудь') також очистить попередній html, можливо, документ не збито в контексті settimeout?
mindandmedia

Відповіді:


109

Схоже, google.load додає скрипт на сторінку за допомогою document.write (), який, якщо використовується після завантаження сторінки, видаляє html.

Це пояснюється більш поглиблено: http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/e07c2606498094e6

Використовуючи одну з ідей, ви можете використовувати зворотний виклик для завантаження, щоб змусити його використовувати додавання, а не doc.write:

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

Це демонструє 2-секундне очікування із затримкою вікна сповіщення


Я не хочу, щоб відображалося вікно попередження, чи є якась робота для цього?
Шойб Мухаммед

4
Попередження було лише прикладом фрагменту коду. Це може бути що завгодно.
хвиля

Це чудово. Єдине, що я змінив на роботу, як я очікував, - це викликати функцію drawChart замість функції оповіщення.
chiurox

Лише додавши порожній параметр зворотного виклику, він зафіксував це для мене.
Адам Б

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!
        }
    } )
}

Роблячи це без зворотного виклику (), я все ще отримую порожню сторінку - але при зворотному дзвінку це для мене виправлено.


5

Примітка. Наступне добре для уникнення затримки в часі - це саме час. Цей приклад може бути використаний загалом у всіх сценаріях (потрібен він), але особливо він використовувався з Greasemonkey. Він також використовує API діаграми Google як приклад, але це рішення виходить за межі інших API Google і може використовуватися в будь-якому місці, де потрібно чекати завантаження сценарію.

Використання google.load із зворотним зв'язком не вирішило проблему під час використання Greasemonkey для додавання діаграми Google. У процесі (Greasemonkey вводиться на сторінку) додається вузол сценарію www.google.com/jsapi. Після додавання цього елемента до JavaScript jsapi JavaScript, введений (або сторінка) скрипт готовий використовувати команду google.load (яку потрібно завантажити у доданий вузол), але цей сценарій jsapi ще не завантажився. Налаштування тайм-ауту спрацювало, але час очікування був просто вирішенням перебігу хронометражу завантаження сценарію Google jsapi із введеним сценарієм / сторінка. Переміщення там, де сценарій виконує 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() {
    // …
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.