Я использую следующий код для динамического загрузки сценария на html-странице (так как я не знаю URL-адреса перед обслуживанием страницы):
let script = document.createElement('script');
script.src = 'https://foo/bar/myscript.js';
script.async = false;
script.defer = false;
document.head.appendChild(script);
//Try to use a global function defined in the script:
myFun(); //This raises "undefined" error
следуя предложению здесь: qaru.site/questions/433329/... Я установил атрибуты async
и defer
для false
, чтобы убедиться, что сценарий загружается, прежде чем пытаться его использовать. Но, как вы можете видеть из комментария в последней строке кода, это не работает.
Что мне здесь не хватает? Обратите внимание, что если я использую setTimeout()
чтобы подождать немного до вызова myFun()
он работает так, как ожидалось, так что это определенно проблема с асинхронной/отложенной загрузкой... но как мне ее исправить? (используя Chrome, кстати)
Вы можете вызвать функцию в сценарии onload
event
let script = document.createElement('script');
script.async = false;
script.defer = false;
document.head.appendChild(script);
script.onload = function(){
// script is loaded
myFun();
}
script.src = 'https://foo/bar/myscript.js';
Попробуем понять, что происходит. Ваш код Javascript пытается загрузить файл с сервера. Загрузка файлов не является быстрой операцией, особенно в том случае, если клиентский компьютер, работающий с веб-браузером, находится далеко от сервера, и запрос должен проходить через различное количество компьютеров. Ваш Javascript-код не ждет сценария. Вместо этого он запускается в продолжении, и скрипт будет загружен, когда он будет успешно загружен. Поэтому вы можете использовать обратный вызов, который запускается при загрузке, например:
let script = document.createElement('script');
script.src = 'https://foo/bar/myscript.js';
script.async = false;
script.defer = false;
document.head.appendChild(script);
script.onload = function() {
myFun();
};
Это позволит убедиться, что сценарий загружается до вашего кода, который должен был быть запущен после загрузки сценария.