在JS内部动态加载JS

我有一个动态网页,我需要在另一个javascript文件中导入一个外部JS文件(在IF条件下)。

我试图寻找一个可行的解决办法,但没有成功。

我尝试使用document.createElement()将JS文件加载到DOM,但它也不起作用。显然,Js被加载到DOM中,但在当前Js文件中无法访问。

解决方案在jQuery也将很好

763957 次浏览

jQuery有$.getScript():

描述:使用GET HTTP请求从服务器加载一个JavaScript文件,然后执行它。

你可以动态加载页面内的js,而不是另一个js文件。

你必须使用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.');
});

你可以使用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.');
});

这个链接应该有助于: http://api.jquery.com/jQuery.getScript/ < / p >

jQuery的$.getScript()有时是bug,所以我使用我自己的实现,如:

jQuery.loadScript = function (url, callback) {
jQuery.ajax({
url: url,
dataType: 'script',
success: callback,
async: true
});
}

像这样使用它:

if (typeof someObject == 'undefined') $.loadScript('url_to_someScript.js', function(){
//Stuff to do after someScript has loaded
});

我猜在你的dom解决方案中,你做了如下的事情:

var script = document.createElement('script');
script.src = something;
//do stuff with the script

首先,这是行不通的,因为脚本没有被添加到文档树中,所以它不会被加载。而且,即使你这样做了,当另一个脚本正在加载时,javascript的执行仍在继续,所以它的内容在脚本完全加载之前是不可用的。

你可以监听脚本的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

下面是一个动态加载javascript和CSS文件的小库:

https://github.com/todotresde/javascript-loader

我想按顺序和动态加载css和js文件是有用的。

支持扩展来加载任何你想要的库,而不仅仅是主文件,你可以用它来加载自定义文件。

例如:

<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="scripts/javascript-loader.js" type="text/javascript" charset="utf-8" ></script>
<script type="text/javascript">
$(function() {


registerLib("threejs", test);


function test(){
console.log(THREE);
}


registerLib("tinymce", draw);


function draw(){
tinymce.init({selector:'textarea'});
}


});
</script>
</head>
<body>
<textarea>Your content here.</textarea>
</body>
如果你有许多文件依赖关系,使用AMD/RequireJS。 http://requirejs.org/ < / p >

我建议使用AMD javascript类文件requirejs

这是一个很好的例子

http://www.sitepoint.com/understanding-requirejs-for-effective-javascript-module-loading/

为了编写我的插件,我需要在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();
}
}
};

更多上下文中的脚本:

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
};


}

jQuery.getScript()方法是Ajax函数的简写(带有dataType属性:$.ajax({ url: url,dataType: "script"}))

如果你想让脚本是可缓存的,要么使用< >强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 );
});

参考:jQuery. getscript () | jQuery API文档 .getscript (

我需要经常这样做,所以我使用这个:

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);

有关更多信息,请参阅这个网站如何在另一个JavaScript文件中包含一个JavaScript文件?,这是我的函数思想的来源。

Necromancing。

我用这个来加载依赖脚本 它与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();

如果你对用来创建这个的__abc0版本感兴趣:

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(let 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
let 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) =>
{
let 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(let 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();
如果要加载脚本的动态列表,请将脚本写入属性,如data-main,例如: <script src="scriptloader.js" data-main="file1.js,file2.js,file3.js,etc." ></script>
并且执行element.getAttribute("data-main").split(',')

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(',')

获取列表。