dynamic加载JS里面的JS
我有一个dynamic网页,我需要在另一个JavaScript文件中导入外部JS文件(在IF
条件下)。
我试图寻找一个可行的解决scheme,但没有奏效。
我曾尝试使用document.createElement()
加载一个JS文件到DOM,但它也没有工作。 显然,Js被加载到DOM中,但在当前JS文件中无法访问。
在jQuery中的解决scheme也没关系
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解决scheme中,你做了如下的事情:
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
我需要经常这样做,所以我使用这个:
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文件? ,这是我的function理念的来源。
您可以dynamic加载页面内的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.'); });
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();
如果你对用于创build这个的typecript -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();
jQuery.getScript()
方法是Ajax函数的简写(具有dataType属性: $.ajax({ url: url,
dataType: "script"
})
)
如果您希望脚本是可以caching的,可以使用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文档
你可以使用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/
我build议使用requirejs与AMD的JavaScript类文件
如何在这里使用它的好例子
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, ie 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()
:
说明 :使用GET HTTP请求从服务器加载JavaScript文件,然后执行它。
你可以使用jQuery的$.getScript()
方法来做到这一点,但如果你想要一个更完整的function, yepnope.js是你的select。 它支持脚本和样式表的条件加载,并且很容易使用。
这里是一个小的lib来dynamic加载JavaScript和CSS文件:
https://github.com/todotresde/javascript-loader
我想是有用的,以有序和dynamic加载CSS和JS文件。
支持扩展来加载你想要的任何库,而不仅仅是主文件,你可以使用它来加载自定义文件。
IE:
<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/