Асинхронная загрузка javascript с помощью document.write

Я пытаюсь async google map api javascript.

Итак, нормальный тег script работает <script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>

Но в следующей версии async нет.

(function () {
    var gmap = document.createElement('script'); gmap.type = 'text/javascript'; gmap.async = true;
    gmap.src = 'https://maps.googleapis.com/maps/api/js?sensor=false';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gmap, s);
})();

После некоторой проверки точки останова + проверки выяснилось, что эта строка не работает должным образом в режиме async.

document.write('<' + 'script src="' + src + '"' + 
' type="text/javascript"><' + '/script>');

Объект документа в режиме синхронизации является "HTMLDocument", но в асинхронном режиме вместо этого "# document". Что-то случилось с объектом документа после загрузки страницы. Мысли?

Приветствия.

Обновление: Этот вопрос больше связан с тем, почему document.write не запускается, а не загружает асинхронную карту google map api. Если вы установите контрольную точку в этой строке, вы увидите, что существует функция document.write. Имеет ли это какое-либо отношение к тому факту, что document.write является родным?

Ответ 1

document.write нельзя вызывать из асинхронного script, потому что он отсоединен от документа, и поэтому ваш парсер JS не знает, куда его поместить. в лучшем случае браузер игнорирует его. в худшем случае он мог бы написать верхнюю часть вашего текущего документа (как в случае вызова document.write после того, как документ завершил загрузку).

К сожалению, единственный ответ - переписать script, который в случае google api, вероятно, не является жизнеспособным вариантом.

Ответ 2

Я столкнулся с очень похожими проблемами при асинхронной загрузке амазонок. Я смог получить document.write в моем приложении для этих ситуаций, изменив его поведение ($ в этом случае относится к jQuery):

document.write = function(content) {
  if (document.currentScript) {
    var src = document.currentScript.src
        .replace(/\#.*$/, '')
        .replace(/\?.*$/, '')
        .replace(/^.*\/\//, '');
    setTimeout(function() {
      var script = $('script').filter(function() {
        var scriptSrc = $(this).attr('src');
        return scriptSrc && scriptSrc.indexOf(src) !== -1;
      });
      $('<div></div>')
          .addClass('doc-write')
          .html(content)
          .insertAfter(script);
    }, 0);
  } else {
    HTMLDocument.prototype.write.apply(document, arguments);
  }
};

Этот подход может быть улучшен, но он работает достаточно хорошо для моих нужд. Надеюсь, вы сочтете это полезным.

Ответ 4

Не используйте document.write() по причинам, объясняемым рынком, и д-ру Молле. Вместо этого используйте appendChild(), как это сделано в Пример загрузки async Google.

Ответ 5

Добавление комментария здесь, так как я столкнулся с этой проблемой. При асинхронной загрузке script (например, нажатием кнопки) следуйте инструкциям точно, как на site.

Сначала я получил ошибку document.write, когда я не дал значение обратного вызова. И после предоставления обратного вызова я получил ошибку window.initialize, потому что... duh... в моем коде не было функции инициализации. Я изменил это на свое имя функции (что-то вроде loadMap), и он начал работать.

Если честно, просто скопируйте код с сайта и он должен работать. Замените window.onload тем, что вам нужно для запуска указанной функции.