我有一个动态网页,我需要在另一个javascript文件中导入外部JS文件(在IF
条件下)。
我试图寻找一个可行的解决方案,但它没有用。
我尝试使用document.createElement()
将JS文件加载到DOM,但它也无效。显然,Js已加载到DOM中,但在当前的JS文件中无法访问。
jQuery中的解决方案也没问题
答案 0 :(得分:459)
我的猜测是,在你的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
答案 1 :(得分:120)
jQuery' s $.getScript()
有时会出错,所以我使用自己的实现方式:
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
});
答案 2 :(得分:67)
我需要经常这样做,所以我用这个:
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);
有关详细信息,请参阅此网站How do I include a JavaScript file in another JavaScript file?,这是我的功能想法的来源。
答案 3 :(得分:21)
您可以动态加载页面内的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.');
});
答案 4 :(得分:11)
Necromaning。
我用它来加载依赖脚本;
它可以与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();
如果您对用于创建此内容的typescript版本感兴趣:
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();
如果要加载动态脚本列表,请将脚本写入属性,例如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(',')
获取清单。
答案 5 :(得分:7)
jQuery.getScript()
方法是Ajax函数的简写(使用dataType属性:$.ajax({ url: url,
dataType: "script"
{{1 }})
如果您希望脚本可以缓存,请使用RequireJS或按照jQuery的示例扩展})
方法,类似于以下内容。
jQuery.getScript
答案 6 :(得分:4)
你可以使用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/
答案 7 :(得分:4)
我建议使用带有AMD javascript类文件的requirejs
这里如何使用它的好例子
http://www.sitepoint.com/understanding-requirejs-for-effective-javascript-module-loading/
答案 8 :(得分:3)
jQuery有$.getScript()
:
说明:使用GET HTTP请求从服务器加载JavaScript文件,然后执行。
答案 9 :(得分:3)
要创作我的插件,我需要在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
};
}
答案 10 :(得分:0)
您可以使用jQuery的$.getScript()
方法来执行此操作,但如果您想要更全面的功能,yepnope.js是您的选择。它支持脚本和样式表的条件加载,并且易于使用。
答案 11 :(得分:0)
这是一个动态加载javascript和CSS文件的小lib:
https://github.com/todotresde/javascript-loader
我认为按顺序和动态加载css和js文件很有用。
支持扩展以加载您想要的任何lib,而不仅仅是主文件,您可以使用它来加载自定义文件。
即:
<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>
答案 12 :(得分:0)
如果依赖 多个文件,请使用AMD / RequireJS。 http://requirejs.org/