Javascript 在 JS 中动态加载 JS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14521108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamically load JS inside JS
提问by Riju Mahna
I have a dynamic web page where I need to import an external JS file (under an IFcondition) inside another javascript file.
我有一个动态网页,我需要IF在另一个 javascript 文件中导入一个外部 JS 文件(在某个条件下)。
I tried to search for a feasible solution but it didn't work.
我试图寻找可行的解决方案,但没有奏效。
I have tried loading a JS file to the DOM using document.createElement()but it also didn't work. Apparently the Js was loaded into the DOM but was not accessible in the current JS file.
我曾尝试使用将 JS 文件加载到 DOM,document.createElement()但它也不起作用。显然 Js 已加载到 DOM 中,但在当前 JS 文件中无法访问。
Solution in jQuery will also be fine
jQuery 中的解决方案也可以
采纳答案by kayen
jQuery's $.getScript()is buggy sometimes, so I use my own implementation of it like:
jQuery$.getScript()有时会出错,所以我使用自己的实现,例如:
jQuery.loadScript = function (url, callback) {
jQuery.ajax({
url: url,
dataType: 'script',
success: callback,
async: true
});
}
and use it like:
并使用它:
if (typeof someObject == 'undefined') $.loadScript('url_to_someScript.js', function(){
//Stuff to do after someScript has loaded
});
回答by Zirak
My guess is that in your DOM-only solution you did something like:
我的猜测是,在您的 DOM-only 解决方案中,您做了类似的事情:
var script = document.createElement('script');
script.src = something;
//do stuff with the script
First of all, that won't work because the script is not added to the document tree, so it won't be loaded. Furthermore, even when you do, execution of javascript continues while the other script is loading, so its content will not be available to you until that script is fully loaded.
首先,这是行不通的,因为脚本没有添加到文档树中,所以它不会被加载。此外,即使您这样做,javascript 的执行也会在另一个脚本加载时继续执行,因此在该脚本完全加载之前,您将无法使用其内容。
You can listen to the script's loadevent, and do things with the results as you would. So:
您可以收听脚本的load事件,并按照您的意愿处理结果。所以:
var script = document.createElement('script');
script.onload = function () {
//do stuff with the script
};
script.src = something;
document.head.appendChild(script); //or something of the likes
回答by Anonymous JS Fan
I need to do this frequently, so I use this:
我需要经常这样做,所以我使用这个:
var loadJS = function(url, implementationCode, location){
//url is URL of external file, implementationCode is the code
//to be called from the file, location is the location to
//insert the <script> element
var scriptTag = document.createElement('script');
scriptTag.src = url;
scriptTag.onload = implementationCode;
scriptTag.onreadystatechange = implementationCode;
location.appendChild(scriptTag);
};
var yourCodeToBeCalled = function(){
//your code goes here
}
loadJS('yourcode.js', yourCodeToBeCalled, document.body);
For more information, see this site How do I include a JavaScript file in another JavaScript file?, which is the source of my function idea.
有关详细信息,请参阅此站点如何在另一个 JavaScript 文件中包含 JavaScript 文件?,这就是我的函数思想的来源。
回答by muthu
You may dynamically load the js inside the page not another js file
您可以在页面内动态加载 js 而不是另一个 js 文件
you have to use the getScriptto load the js file
你必须使用getScript来加载 js 文件
$.getScript("ajax/test.js", function(data, textStatus, jqxhr) {
console.log(data); //data returned
console.log(textStatus); //success
console.log(jqxhr.status); //200
console.log('Load was performed.');
});
回答by Stefan Steiger
Necromaning.
死灵法术。
I use this to load dependant scripts;
it works with IE8+ without adding any dependency on another library like jQuery !
我用它来加载依赖脚本;
它适用于 IE8+,无需添加对其他库(如 jQuery)的任何依赖!
var cScriptLoader = (function ()
{
function cScriptLoader(files)
{
var _this = this;
this.log = function (t)
{
console.log("ScriptLoader: " + t);
};
this.withNoCache = function (filename)
{
if (filename.indexOf("?") === -1)
filename += "?no_cache=" + new Date().getTime();
else
filename += "&no_cache=" + new Date().getTime();
return filename;
};
this.loadStyle = function (filename)
{
// HTMLLinkElement
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = _this.withNoCache(filename);
_this.log('Loading style ' + filename);
link.onload = function ()
{
_this.log('Loaded style "' + filename + '".');
};
link.onerror = function ()
{
_this.log('Error loading style "' + filename + '".');
};
_this.m_head.appendChild(link);
};
this.loadScript = function (i)
{
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = _this.withNoCache(_this.m_js_files[i]);
var loadNextScript = function ()
{
if (i + 1 < _this.m_js_files.length)
{
_this.loadScript(i + 1);
}
};
script.onload = function ()
{
_this.log('Loaded script "' + _this.m_js_files[i] + '".');
loadNextScript();
};
script.onerror = function ()
{
_this.log('Error loading script "' + _this.m_js_files[i] + '".');
loadNextScript();
};
_this.log('Loading script "' + _this.m_js_files[i] + '".');
_this.m_head.appendChild(script);
};
this.loadFiles = function ()
{
// this.log(this.m_css_files);
// this.log(this.m_js_files);
for (var i = 0; i < _this.m_css_files.length; ++i)
_this.loadStyle(_this.m_css_files[i]);
_this.loadScript(0);
};
this.m_js_files = [];
this.m_css_files = [];
this.m_head = document.getElementsByTagName("head")[0];
// this.m_head = document.head; // IE9+ only
function endsWith(str, suffix)
{
if (str === null || suffix === null)
return false;
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
for (var i = 0; i < files.length; ++i)
{
if (endsWith(files[i], ".css"))
{
this.m_css_files.push(files[i]);
}
else if (endsWith(files[i], ".js"))
{
this.m_js_files.push(files[i]);
}
else
this.log('Error unknown filetype "' + files[i] + '".');
}
}
return cScriptLoader;
})();
var ScriptLoader = new cScriptLoader(["foo.css", "Scripts/Script4.js", "foobar.css", "Scripts/Script1.js", "Scripts/Script2.js", "Scripts/Script3.js"]);
ScriptLoader.loadFiles();
If you are interested in the typescript-version used to create this:
如果您对用于创建它的typescript-version感兴趣:
class cScriptLoader {
private m_js_files: string[];
private m_css_files: string[];
private m_head:HTMLHeadElement;
private log = (t:any) =>
{
console.log("ScriptLoader: " + t);
}
constructor(files: string[]) {
this.m_js_files = [];
this.m_css_files = [];
this.m_head = document.getElementsByTagName("head")[0];
// this.m_head = document.head; // IE9+ only
function endsWith(str:string, suffix:string):boolean
{
if(str === null || suffix === null)
return false;
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
for(var i:number = 0; i < files.length; ++i)
{
if(endsWith(files[i], ".css"))
{
this.m_css_files.push(files[i]);
}
else if(endsWith(files[i], ".js"))
{
this.m_js_files.push(files[i]);
}
else
this.log('Error unknown filetype "' + files[i] +'".');
}
}
public withNoCache = (filename:string):string =>
{
if(filename.indexOf("?") === -1)
filename += "?no_cache=" + new Date().getTime();
else
filename += "&no_cache=" + new Date().getTime();
return filename;
}
public loadStyle = (filename:string) =>
{
// HTMLLinkElement
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = this.withNoCache(filename);
this.log('Loading style ' + filename);
link.onload = () =>
{
this.log('Loaded style "' + filename + '".');
};
link.onerror = () =>
{
this.log('Error loading style "' + filename + '".');
};
this.m_head.appendChild(link);
}
public loadScript = (i:number) =>
{
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = this.withNoCache(this.m_js_files[i]);
var loadNextScript = () =>
{
if (i + 1 < this.m_js_files.length)
{
this.loadScript(i + 1);
}
}
script.onload = () =>
{
this.log('Loaded script "' + this.m_js_files[i] + '".');
loadNextScript();
};
script.onerror = () =>
{
this.log('Error loading script "' + this.m_js_files[i] + '".');
loadNextScript();
};
this.log('Loading script "' + this.m_js_files[i] + '".');
this.m_head.appendChild(script);
}
public loadFiles = () =>
{
// this.log(this.m_css_files);
// this.log(this.m_js_files);
for(var i:number = 0; i < this.m_css_files.length; ++i)
this.loadStyle(this.m_css_files[i])
this.loadScript(0);
}
}
var ScriptLoader = new cScriptLoader(["foo.css", "Scripts/Script4.js", "foobar.css", "Scripts/Script1.js", "Scripts/Script2.js", "Scripts/Script3.js"]);
ScriptLoader.loadFiles();
If it's to load a dynamic list of scripts, write the scripts into an attribute, such as data-main, e.g.
<script src="scriptloader.js" data-main="file1.js,file2.js,file3.js,etc." ></script>
and do a element.getAttribute("data-main").split(',')
如果是加载一个动态的脚本列表,将脚本写入一个属性中,比如data-main,eg
<script src="scriptloader.js" data-main="file1.js,file2.js,file3.js,etc." ></script>
并做一个element.getAttribute("data-main").split(',')
such as
如
var target = document.currentScript || (function() {
var scripts = document.getElementsByTagName('script');
// Note: this is for IE as IE doesn't support currentScript
// this does not work if you have deferred loading with async
// e.g. <script src="..." async="async" ></script>
// https://web.archive.org/web/20180618155601/https://www.w3schools.com/TAgs/att_script_async.asp
return scripts[scripts.length - 1];
})();
target.getAttribute("data-main").split(',')
to obtain the list.
以获取列表。
回答by Trent
The jQuery.getScript()method is a shorthand of the Ajax function (with the dataType attribute: $.ajax({ url: url,dataType: "script"}))
该jQuery.getScript()方法是Ajax的函数的速记(与数据类型属性:)$.ajax({ url: url,dataType: "script"})
If you want the scripts to be cachable, either use RequireJSor follow jQuery's example on extending the jQuery.getScriptmethod similar to the following.
如果您希望脚本可缓存,请使用RequireJS或按照 jQuery 的示例扩展jQuery.getScript类似于以下的方法。
jQuery.cachedScript = function( url, options ) {
// Allow user to set any option except for dataType, cache, and url
options = $.extend( options || {}, {
dataType: "script",
cache: true,
url: url
});
// Use $.ajax() since it is more flexible than $.getScript
// Return the jqXHR object so we can chain callbacks
return jQuery.ajax( options );
};
// Usage
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
console.log( textStatus );
});
回答by aqm
I'm recommend using requirejs with AMD javascript class files
我建议在 AMD javascript 类文件中使用 requirejs
good example of how to use it here
如何在这里使用它的好例子
http://www.sitepoint.com/understanding-requirejs-for-effective-javascript-module-loading/
http://www.sitepoint.com/understanding-requirejs-for-effective-javascript-module-loading/
回答by Hazem Hagrass
You can do it using JQuery:
您可以使用 JQuery 做到这一点:
$.getScript("ajax/test.js", function(data, textStatus, jqxhr) {
console.log(data); //data returned
console.log(textStatus); //success
console.log(jqxhr.status); //200
console.log('Load was performed.');
});
this link should help: http://api.jquery.com/jQuery.getScript/
这个链接应该有帮助:http: //api.jquery.com/jQuery.getScript/
回答by Blender
jQuery has $.getScript():
jQuery 有$.getScript():
Description: Load a JavaScript file from the server using a GET HTTP request, then execute it.
描述:使用 GET HTTP 请求从服务器加载 JavaScript 文件,然后执行它。
回答by Luke Madhanga
To author my plugin I needed to load external scripts and styles inside a JS file, all of which were predefined. To achieve this, I did the following:
为了编写我的插件,我需要在 JS 文件中加载外部脚本和样式,所有这些都是预定义的。为了实现这一点,我做了以下事情:
this.loadRequiredFiles = function (callback) {
var scripts = ['xx.js', 'yy.js'];
var styles = ['zz.css'];
var filesloaded = 0;
var filestoload = scripts.length + styles.length;
for (var i = 0; i < scripts.length; i++) {
log('Loading script ' + scripts[i]);
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scripts[i];
script.onload = function () {
log('Loaded script');
log(this);
filesloaded++; // (This means increment, i.e. add one)
finishLoad();
};
document.head.appendChild(script);
}
for (var i = 0; i < styles.length; i++) {
log('Loading style ' + styles[i]);
var style = document.createElement('link');
style.rel = 'stylesheet';
style.href = styles[i];
style.type = 'text/css';
style.onload = function () {
log('Loaded style');
log(this);
filesloaded++;
finishLoad();
};
document.head.appendChild(style);
}
function finishLoad() {
if (filesloaded === filestoload) {
callback();
}
}
};
More of the script in context:
上下文中的更多脚本:
function myPlugin() {
var opts = {
verbose: false
}; ///< The options required to run this function
var self = this; ///< An alias to 'this' in case we're in jQuery ///< Constants required for this function to work
this.getOptions = function() {
return opts;
};
this.setOptions = function(options) {
for (var x in options) {
opts[x] = options[x];
}
};
/**
* @brief Load the required files for this plugin
* @param {Function} callback A callback function to run when all files have been loaded
*/
this.loadRequiredFiles = function (callback) {
var scripts = ['xx.js', 'yy.js'];
var styles = ['zz.css'];
var filesloaded = 0;
var filestoload = scripts.length + styles.length;
for (var i = 0; i < scripts.length; i++) {
log('Loading script ' + scripts[i]);
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scripts[i];
script.onload = function () {
log('Loaded script');
log(this);
filesloaded++;
finishLoad();
};
document.head.appendChild(script);
}
for (var i = 0; i < styles.length; i++) {
log('Loading style ' + styles[i]);
var style = document.createElement('link');
style.rel = 'stylesheet';
style.href = styles[i];
style.type = 'text/css';
style.onload = function () {
log('Loaded style');
log(this);
filesloaded++;
finishLoad();
};
document.head.appendChild(style);
}
function finishLoad() {
if (filesloaded === filestoload) {
callback();
}
}
};
/**
* @brief Enable user-controlled logging within this function
* @param {String} msg The message to log
* @param {Boolean} force True to log message even if user has set logging to false
*/
function log(msg, force) {
if (opts.verbose || force) {
console.log(msg);
}
}
/**
* @brief Initialise this function
*/
this.init = function() {
self.loadRequiredFiles(self.afterLoadRequiredFiles);
};
this.afterLoadRequiredFiles = function () {
// Do stuff
};
}

