在我的插件中有条件地加载外部javascript库
conditionally loading external javascript libraries in my plugin
我已经编写了一个插件,它依赖于我想要有条件地包含的外部库,也就是说,如果用户的网站已经有这些库,用户可以选择不自动包含这些库。下面是一些伪代码来说明的问题
<script type="text/javascript" src="path/to/plugin.js"></script>
<script type="text/javascript">
PLUGIN.init({
"param1": "foo",
"parma2": 33,
"include": {"jquery": 0, "googlemaps": 0}
});
</script>
在我的插件脚本中
var PLUGIN = {
"init": function(obj) {
if (obj.include.googlemaps !== 0) {
document.write('<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true&v=3.6">'x3C/script>');
}
if (obj.include.jquery !== 0) {
document.write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js">'x3C/script>');
}
.. do more things ..
}
问题是,当我准备"做更多的事情"时,库似乎还没有加载。我得到一个错误,jquery找不到,或者谷歌地图找不到。我可以通过将代码更改为来解决这个问题
document.write('<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true&v=3.6">'x3C/script>');
document.write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js">'x3C/script>');
var PLUGIN = {
"init": function(obj) {
.. do more things ..
}
但是现在用户无法控制是否加载库。建议?解决方法?
更新:谢谢大家的建议,但到目前为止没有任何乐趣。以下是我正在做的事情和正在发生的事情。由于我可能正在加载0个或更多的脚本(用户可以选择决定哪些脚本不需要加载),我已经将我的代码设置为
"importLib": function(libPath, callback) {
var newLib = document.createElement("script");
if (callback !== null) {
newLib.onload = callback;
}
newLib.src = libPath;
document.head.appendChild(newLib);
},
"init": function(obj) {
var scripts = [];
if (obj.include.googlemaps !== 0) {
scripts.push("http://maps.google.com/maps/api/js?sensor=true&v=3.6");
}
if (obj.include.jquery !== 0) {
scripts.push("http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js");
}
if (obj.include.anotherlib !== 0) {
scripts.push("http://path/to/another/lib.js");
}
var len_scripts = scripts.length,
callback = null;
if (len_scripts > 0) {
for (var i = 0; i < len_scripts; i++) {
// add callback only on the last lib to be loaded
if (i == len_scripts - 1) {
callback = function() { startApp(obj) };
}
importLib(scripts[i], callback);
}
}
// Start the app rightaway if no scripts need to be loaded
else {
startApp(obj);
}
},
"startApp": function(obj) {
}
发生的情况是,Firefox发出一个attempt to run compile-and-go script on a cleared scope
错误,Safari没有收到这个错误,但没有加载任何内容。有趣的是,Safari错误控制台显示没有任何错误。Firefox错误似乎是由document.head.appendChild(newLib);
行引起的,如果我对此发表评论,错误就会消失,但当然,网页加载不正确。
您应该将每个脚本添加为DOM节点,并在完成加载后使用onload
属性执行操作。
function importLib(libPath, callback) {
var newLib = document.createElement("script");
newLib.onload = callback;
newLib.src = libPath;
document.head.appendChild(newLib);
}
上面,libPath
参数是库的URL,callback
参数是加载完成时要调用的函数。您可以按如下方式使用它:
importLib("http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js", function() {
alert("jquery loaded!");
nowDoSomething(aboutIt);
});
顺便说一句:一般来说,document.write
不是大多数问题的好解决方案(但我不会说永远是正确的解决方案——每个规则都有例外)。
上述解决方案可以在现代浏览器中使用,但对于IE 7/8,您可能需要添加一些额外的代码,比如:
function importLib(libPath, callback) {
var newLib = document.createElement("script");
if (navigator.userAgent.indexOf('MSIE') !== -1) {
newLib.onreadystatechange = function () {// this piece is for IE 7 and 8
if (this.readyState == 'complete') {
callback();
}
};
} else {
newLib.onload = callback;
}
newLib.src = libPath;
document.head.appendChild(newLib);
}
我遇到了同样的问题。如果您在.NET中编写网站,一种解决方法是在从代码隐藏加载页面之前有条件地编写脚本引用。我的问题是,当远程用户通过VPN访问我的应用程序时,它会阻止访问互联网,因此无法引用谷歌地图。这会阻止页面的其余部分在合理的时间范围内加载。我尝试通过jQuery的getScript()命令控制谷歌地图库的脚本引用,但正如您所发现的,后续的谷歌地图配置代码在引用外部库之前运行。
我的解决方案是有条件地从代码背后引用谷歌地图:
VB(代码隐藏):
'if VPN mode is not enable, add the external google maps script reference (this speeds up the interface when using VPN significantly)
If Session("VPNMode") = False Then
Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder()
sb.AppendLine("")
sb.AppendLine("<script type='text/javascript'")
sb.Append(" src='http://maps.google.com/maps/api/js?v=3&sensor=false'>")
sb.Append("</script>")
Dim header As LiteralControl = New LiteralControl
header.Text = sb.ToString()
Me.Page.Header.Controls.Add(header)
End If
客户端脚本(javascript):
<script type='text/javascript'>
$(function () {
if ($("input[name*='VPN']").is(":checked"))
{ }
else {
loadGoogleMap()
}
});
function loadGoogleMap() {
hazsite = new google.maps.LatLng(hazLat, hazLong);
map = new google.maps.Map(document.getElementById('map_canvas'), { zoom: 18, center: hazsite, mapTypeId: google.maps.MapTypeId.SATELLITE });
var marker = new google.maps.Marker({
position: hazsite,
map: map,
title: "Site Location"
});
}
</script>
- 使用javascript在Flash中加载外部图像
- 如何在运行时在angular 2中加载外部js脚本
- Chrome扩展无法通过清单加载外部javascript
- 加载Angular视图后加载外部脚本
- Cordova/Phonegap在主要的Cordova网络视图中加载外部站点
- IE 9 BHO插件.加载外部JS文件时出现错误SCRIPT1014
- 是否有用于加载外部脚本的JavaScript库
- 使用纯Javascript加载外部URL内容
- 在Chrome扩展中加载外部javascript
- 在扩展 jQuery 之前加载外部资源
- 无法加载外部 JavaScript 文件 - Codeigniter
- jquery .load() 不加载外部 JS
- GO - html 文件无法加载外部 js 文件
- jQuery 不会使用 .load() 加载外部 html 模板
- 使用HTML5缓存时无法加载外部资源
- 色盒延迟打开;锁定“;当加载外部javascript文件时
- 使用load()加载外部文件,然后使用fancybox插件进行修改并显示
- 在Ember应用程序中加载外部域脚本
- html javascript加载外部脚本
- 如何防止加载外部资源,同时防止“在'文档'上执行'写入'失败”错误