Асинхронная загрузка 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);
}
};
Этот подход может быть улучшен, но он работает достаточно хорошо для моих нужд. Надеюсь, вы сочтете это полезным.
Ответ 3
Когда вы используете параметр callback
внутри script -URL, script не использует write()
, и вы сможете загружать API асинхронно.
Смотрите: https://developers.google.com/maps/documentation/javascript/tutorial?hl=en#asynch
Ответ 4
Не используйте document.write()
по причинам, объясняемым рынком, и д-ру Молле. Вместо этого используйте appendChild()
, как это сделано в Пример загрузки async Google.
Ответ 5
Добавление комментария здесь, так как я столкнулся с этой проблемой. При асинхронной загрузке script (например, нажатием кнопки) следуйте инструкциям точно, как на site.
Сначала я получил ошибку document.write
, когда я не дал значение обратного вызова. И после предоставления обратного вызова я получил ошибку window.initialize
, потому что... duh... в моем коде не было функции инициализации. Я изменил это на свое имя функции (что-то вроде loadMap), и он начал работать.
Если честно, просто скопируйте код с сайта и он должен работать. Замените window.onload
тем, что вам нужно для запуска указанной функции.