日期:2014-05-16 浏览次数:20327 次
?Javascript不比Java,没有import关键字(据说Javascript2.0将加入Import和命名空间)。在网上查了很多别 人写的Import函数的代码,通常都是直接在HTML里插入script元素来实现。这种方式无法实现同步导入,即import函数调用的下面无法马上 使用导入JS里面的变量。
下面的代码将使用AJAX方式来实现Import功能,可以实现同步导入。调用方式很简单,在JS代码开始处调用$import()函数就可以了。
另外本代码还集成了CSS的导入,虽然很简单但也很有用。因为如果你编写了一个JS文件来实现某种控件,你肯定不希望使用你的JS文件的人还要在他自己的代码里引入你的CSS文件。所以你可以使用本代码里的$import函数在你的JS文件中引用你的CSS文件。
最后,本代码还提供了一个很振奋的功能,即为你导入的JS文件中的全局变量加上命名前缀。我们在很多高级语言中都可以做到这一点,如引用JAVA的JSP标签库,<%@ taglib uri="http://java.sun.com/jsp/jstl/core " prefix="c"%>,这个库里面的内容可以用前缀C与其他标签库区分开来。本代码也提供了类似的功能,如:$import("../lib/head.js","h")。之后就可以用h.XXX来引用head.js里定义的函数和变量了。
代码如下:
/** * 这个JS文件提供了命名空间、JS文件导入功能。 注:import本身是个关键字,不能用来做变量函数名 * 通过本代码可以导入Javascript文件,可以使用绝对URL和相对URL作为路径 $import("../lib/head.js"); * $import("head.js"); 可以导入CSS文件 $import("head.css"); * 导入Javascript文件时,可以为导入文件里所定义的全局变量增加前缀,如: $import("prototype.js","p"); var * mydiv = p.$("myDiv"); * 但只有用var定义的全局变量和全局函数将增加前缀,而没有用var定义的变量将被视为必须要为全局的变量,不增加前缀 * * @author 由月 */ var Import = {}; Import.importedJSFiles = []; Import.importingJSFiles = []; Import.importedCSSFiles = []; Import.$import = function(url, prefix) { // 检查参数合法 if (url == null || url == "") return; // 获取导入文件的完整URL var fullUrl = Import.getFullPathFromUrl(url); // 先将此URL放入正在导入的列表中 Import.addImportingFile(fullUrl); // 判断导入的是JS文件还是CSS文件 if(Import.getFileType(fullUrl) == ".js"){ Import.importJS(fullUrl, prefix); } else { Import.importCSS(fullUrl); } // 将URL从正在导入列表中移除,并加入已导入列表 Import.addImportedFile(fullUrl); }; Import.importCSS = function(url) { // 检查此文件是否已经被导入过 if (Import.isImported(url)) return; var head = document.getElementsByTagName("head")[0]; // IE6 cannot support appendchild for head when BASE tag is present. // So we have to use document.write as instead. // We need better solution for this IE bug. // var link = head.appendChild(document.createElement("link")); var link = document.createElement("link"); link.href = url; link.type = "text/css"; link.rel = "stylesheet"; if (document.readyState == "complete") { // if this method is called after the page loaded, for example, // in a script with defer tag, then use appendChild, // otherwise the document will be cleared when invoking // document.write. head.appendChild(link); } else { document.write(link.outerHTML); } }; Import.importJS = function(url, prefix) { // 检查此文件是否已经被导入过 if (Import.isImported(url)) return; // 通过AJAX获取文件内容 // alert(url); var script = Import.getScriptContent(url); // alert(script); // 加上命名空间并执行脚本 Import.execute(script, prefix); }; Import.execute = function(script, prefix) { if (prefix != null && prefix != "") { var variables = Import.analysScript(script); // 分析出脚本中所有的全局变量 if (variables.length > 0) { var pre = eval(prefix + " = {};"); // 根据prefix生成对象 for ( var i = 0; i < variables.length; i++) { var variable = variables[i]; // alert(variable); pre[variable] = null; } var extendScript = "; var pre=" + prefix + ";for(var attr in pre){try{pre[attr]=eval(attr);}catch(e){}}"; var wholeScript = "(function(){" + script + extendScript + "})();"; window.execScript(wholeScript); } } else { window.execScript(script); } }; Import.analysScript = function(script) { // 检查参数 if (script == null || script == "") return null; var globalVariables = null; // 定义词法状态机 var wordStateMachine = { currentState : "init", // 状态机的当前状态 wordCache : [], // 保存用来构造单词的缓存 stateObj : {}, // 保存状态间变量 getStateObj : function(state) { if (state && state != "") { if (this.stateObj[state] == null) this.stateObj[state] = {}; return this.stateObj[state]; } return null; }, process : function(script) { var self = this; var index = 0; var outputWords = []; while (index < script.length) { var c = script.charAt(index); var result = "self"