我正在使用模块模式,我想要做的事情之一就是动态地包含一个外部JavaScript文件,执行该文件,然后使用return { }我模块中文件中的函数/变量.
我无法弄清楚如何轻松地做到这一点.是否有任何标准方法来执行伪同步外部脚本加载?
function myModule() {
var tag = document.createElement("script");
tag.type = "text/javascript";
tag.src = "http://some/script.js";
document.getElementsByTagName('head')[0].appendChild(tag);
//something should go here to ensure file is loaded before return is executed
return {
external: externalVariable
}
}
Run Code Online (Sandbox Code Playgroud)
Sea*_*sey 54
只有一种方法可以同步加载和执行脚本资源,即使用同步XHR
这是如何执行此操作的示例
// get some kind of XMLHttpRequest
var xhrObj = createXMLHTTPObject();
// open and send a synchronous request
xhrObj.open('GET', "script.js", false);
xhrObj.send('');
// add the returned content to a newly created script tag
var se = document.createElement('script');
se.type = "text/javascript";
se.text = xhrObj.responseText;
document.getElementsByTagName('head')[0].appendChild(se);
Run Code Online (Sandbox Code Playgroud)
但是你通常不应该使用同步请求,因为这会阻止其他一切.但话虽如此,当然有适合的情况.
我可能会使用onload处理程序将包含函数重构为异步模式.
Nei*_*eil 39
该接受的答案是不正确的.
同步加载文件与同步执行文件不同 - 这是OP请求的.
接受的答案加载文件同步,但只是将脚本标记附加到DOM.只是因为appendChild()已经返回并不能保证脚本已经完成执行并且它的成员被初始化以供使用.
实现OP问题的唯一(见警告)方法是如上所述同步加载XHR上的脚本,然后作为文本读取并传入eval()或新的Function()调用并等待该函数返回.这是保证脚本同步加载和执行的唯一方法.
我没有评论从UI或安全角度来看这是否是明智的做法,但肯定有用例证明同步加载和执行是合理的.
警告:除非你使用网络工作者,否则只需调用loadScripts();
小智 10
这是我在我的应用程序中用于多个文件加载的代码.
Utilities.require = function (file, callback) {
callback = callback ||
function () {};
var filenode;
var jsfile_extension = /(.js)$/i;
var cssfile_extension = /(.css)$/i;
if (jsfile_extension.test(file)) {
filenode = document.createElement('script');
filenode.src = file;
// IE
filenode.onreadystatechange = function () {
if (filenode.readyState === 'loaded' || filenode.readyState === 'complete') {
filenode.onreadystatechange = null;
callback();
}
};
// others
filenode.onload = function () {
callback();
};
document.head.appendChild(filenode);
} else if (cssfile_extension.test(file)) {
filenode = document.createElement('link');
filenode.rel = 'stylesheet';
filenode.type = 'text/css';
filenode.href = file;
document.head.appendChild(filenode);
callback();
} else {
console.log("Unknown file type to load.")
}
};
Utilities.requireFiles = function () {
var index = 0;
return function (files, callback) {
index += 1;
Utilities.require(files[index - 1], callBackCounter);
function callBackCounter() {
if (index === files.length) {
index = 0;
callback();
} else {
Utilities.requireFiles(files, callback);
}
};
};
}();
Run Code Online (Sandbox Code Playgroud)
并且可以使用此实用程序
Utilities.requireFiles(["url1", "url2",....], function(){
//Call the init function in the loaded file.
})
Run Code Online (Sandbox Code Playgroud)
我能想出的最类似Node.js的实现能够同步加载JS文件,并将它们用作对象/模块
var scriptCache = [];
var paths = [];
function Import(path)
{
var index = 0;
if((index = paths.indexOf(path)) != -1) //If we already imported this module
{
return scriptCache [index];
}
var request, script, source;
var fullPath = window.location.protocol + '//' + window.location.host + '/' + path;
request = new XMLHttpRequest();
request.open('GET', fullPath, false);
request.send();
source = request.responseText;
var module = (function concealedEval() {
eval(source);
return exports;
})();
scriptCache.push(module);
paths.push(path);
return module;
}
Run Code Online (Sandbox Code Playgroud)
示例source(addobjects.js):
function AddTwoObjects(a, b)
{
return a + b;
}
this.exports = AddTwoObjects;
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
var AddTwoObjects = Import('addobjects.js');
alert(AddTwoObjects(3, 4)); //7
//or even like this:
alert(Import('addobjects.js')(3, 4)); //7
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
63073 次 |
| 最近记录: |