javascript - 如何在调用需要其中一个文件的其他 js 文件之前动态添加文件
问题描述
首先,感谢您阅读我的问题并尝试帮助我并为我的英语道歉。
我有以下问题...
我正在动态添加 js 文件和 css 文件,但有时会出现错误,因为首先加载静态 js 文件,然后再下载动态添加的两个文件。
怎样才能解决这个问题?在下载动态添加的两个文件之前,不要加载 js 文件(mapfunctions.js)
我的 api js 文件,调用一个函数,添加动态 js 文件和 css 文件,如您所见。
这是我的 index.html 代码:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Map Generator</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
// this file add dinamically a js file and a css file
<script src="./js/api/api.js"></script>
// this file needs js file added dinamically, and if is not downloaded crash
<script src="./js/option2/mapfunctions.js"></script>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:50%; height:50%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
customMap.addMap("5b4f12233cfb101f4c2d0537", "map");
});
</script>
</body>
</html>
有时显示的错误是:
Error: ReferenceError: mapboxgl is not defined at Object.createMap
这是我的 api.js 文件:
let mapboxJsUrl = 'https://api.tiles.mapbox.com/mapbox-gl-js/v0.46.0/mapbox-gl.js';
let mapboxCssUrl = 'https://api.tiles.mapbox.com/mapbox-gl-js/v0.46.0/mapbox-gl.css';
(function(window, document) {
var includeJSFiles = function(url) {
var apiJs = document.getElementsByTagName("script")[0];
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", url);
var css = includeCss(mapboxCssUrl);
if (apiJs !== undefined) {
head.insertBefore(script, apiJs);
} else {
head.insertBefore(script, head.firstChild);
}
head.insertBefore(css, script);
};
var includeCss = function(url) {
var css = document.createElement("link");
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", url);
return css;
};
includeJSFiles(mapboxJsUrl);
}(window, document));
解决方案
在这种情况下,您最安全的选择可能是使用对象load
上的事件window
。根据 MDN, load
只有在所有资源和依赖项都已加载时才会触发,这样可能会更适合您的情况。
我对 mapbox 不熟悉,但是经过一些研究后,我发现您尝试使用的 api 将mapboxgl
在您的window context
.
看到 ascustomMap
没有在任何地方定义,我改为检查是否存在mapboxgl
onwindow
以验证 Mapbox API 是否动态加载到您的示例中。我对您的代码进行了以下调整以实现动态加载的 mapbox 脚本:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Map Generator</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
// this file add dinamically a js file and a css file
<script src="./js/api/api.js"></script>
// this file needs js file added dinamically, and if is not downloaded crash
<script src="./js/option2/mapfunctions.js"></script>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:50%; height:50%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
/* UPDATE
Add event listener to window object, and register handler on the load event
*/
window.addEventListener('load', function(e) {
customMap.addMap("5b4f12233cfb101f4c2d0537", "map");
});
</script>
</body>
</html>
此外,在您的api.js
脚本中,您应该进行以下调整以促进这一点:
(function(window, document) {
var includeJSFiles = function(url) {
//var apiJs = document.getElementsByTagName("script")[0];
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", url);
// UPDATE
// Keep this simple, and insert the script as head's first node
head.insertBefore(script, head.firstChild);
var css = includeCss(mapboxCssUrl);
head.insertBefore(css, script);
};
var includeCss = function(url) {
var css = document.createElement("link");
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", url);
return css;
};
includeJSFiles(mapboxJsUrl);
}(window, document));
希望这对你有帮助!
推荐阅读
- android - How to have similar mechanism of center-crop on ExoPlayer's PlayerView , but not on the center?
- c++ - 如何使用 C++ 以编程方式读取地理数据
- java - 带有 slif4j 日志的 try catch 块的模拟测试问题
- java - 如何使用 jdt 重命名字段
- vue.js - Vuex 向组件返回一些数据
- ionic-framework - Ionic 4 - AlertController:属性“当前”不存在 - Angular?
- javascript - 如何检测 MDC Snackbar 是否在 JS 中关闭?
- asp.net-core - 在 Azure 中托管时,AspNet Core 日志记录工作但不在 ServiceStack 服务中
- python - Python virtualenv Windows
- python - 用于获取 Outlook 笔记的 rest api