读书人

像C++同样写JavaScript

发布时间: 2013-09-05 16:02:06 作者: rapoo

像C++一样写JavaScript

像C++一样写JavaScript

C/C++/Java的include或import可以引用第3方文件和包. 这个功能在Html/Js里没有默认的实现. 假设我们有这样一个HTML文件index.html:

/** * prerequisite.js *    included before all *.js *  version: 0.0.1 *  cheungmine * 2012-5 */(function (window, undefined) {    "use strict";    window.UTIL = {}    /* Modify DEBUG = false if release */    var DEBUG = true;    var log = function () {        if (window.UTIL.DEBUG === true) {            /* Thanks to Paul Irish for this one:             * http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/             */            log.history = log.history || [];            log.history.push(arguments);            /* Make sure console is present */            if ('object' === typeof console) {                /* Setup console and arguments */                var c = console[console.warn? 'warn':'log'],                    args = Array.prototype.slice.call(arguments),                    a;                /* Add marker to first argument if it's a string */                if (typeof arguments[0] === 'string') {                    /* args[0] = 'your marker: ' + args[0]; */                }                /* Apply console.warn or .log if not supported */                a = c.apply? c.apply(console, args) : c(args);            }        }    };    var getScriptPath = function (jsfile) {        var e = {};        var htmlPath = "";        var jsPath = "";        if (document.location.protocol === 'file:'){            e.BasePath = unescape(document.location.pathname.substr(1));            e.BasePath = 'file://' + e.BasePath.substring(0,e.BasePath.lastIndexOf('/')+1);            e.FullBasePath = e.BasePath;        } else {            e.BasePath = document.location.pathname.substring(0,document.location.pathname.lastIndexOf('/')+1);            e.FullBasePath = document.location.protocol + '//' + document.location.host + e.BasePath;        }        htmlPath = e.FullBasePath;         var i, at, src, slc, scriptTag = document.getElementsByTagName("script");        for (i = 0; i < scriptTag.length; i++) {            src = scriptTag[i].src;            at = src.lastIndexOf(jsfile);            if (at!==-1) {                at++;                slc=src.toLowerCase();                if (slc.indexOf("file://") === 0) {                    jsPath = src.substring(0,at);                    break;                } else if (slc.indexOf("http://") === 0) {                    jsPath = src.substring(0,at);                    break;                } else if (slc.indexOf("https://") === 0) {                    jsPath = src.substring(0,at);                    break;                } else if (slc.indexOf("../") === 0) {                    jsPath = htmlPath + src.substring(0,at);                    break;                } else if (slc.indexOf("./") === 0) {                    jsPath = htmlPath + src.substring(0,at);                    break;                } else if (slc.indexOf("/") === 0) {                    if (document.location.protocol === 'http:' || document.location.protocol === 'https:') {                        jsPath = document.location.protocol + "//" + document.location.host + src.substring(0,at);                    }                    break;                } else if (slc.search(/^([a-z]{1}):/) >= 0) {                    jsPath = src.substring(0,at);                    break;                } else {                    jsPath = htmlPath;                }            }        }        return jsPath;    };        var getScriptName = function () {        var js = document.scripts;        return js[js.length-1].src.substring(js[js.length-1].src.lastIndexOf("/"));    }    var appendScript = function (url, source, head) {        if ( source && !document.getElementById(url) ) {            var oHead = head ? head : document.getElementsByTagName("HEAD").item(0);            var oScript = document.createElement("script");            oScript.language = "javascript";            oScript.type = "text/javascript";            oScript.id = url;            oScript.defer = true;            oScript.text = source;            oHead.appendChild(oScript);        }    }    var importScripts = (function (globalEval) {        var oHead = document.getElementsByTagName("HEAD").item(0);        var xhr = null;        if (window.XMLHttpRequest) {            xhr = new XMLHttpRequest();        } else if ( window.ActiveXObject ) {            try {                xhr = new ActiveXObject("MsXml2.XmlHttp");            } catch (e) {                xhr = new ActiveXObject("Microsoft.XMLHTTP");            }        }        if (! xhr) {            throw "prerequisite.js: XMLHttpRequest Not supported."        }        var basePath = null;        return function importScripts () {            var                args = Array.prototype.slice.call(arguments),                len = args.length,                i = 0,                meta,                data,                content            ;            if (!basePath) {                basePath = getScriptPath(getScriptName());            }            for (; i<len; i++) {                var url = basePath + args[i];                if (url.substr(0, 5).toLowerCase() === "data:") {                    data = url;                    content = data.indexOf(",");                    meta = data.substr(5,content).toLowerCase();                    data = decodeURIComponent(data.substr(content+1));                    if (/;\s*base64\s*[;,]/.test(meta)) {                        data=atob(data);                    }                    if (/;\s*charset=[uU][tT][fF]-?8\s*[;,]/.test(meta)) {                        data = decodeURIComponent(escape(data));                    }                } else {                    xhr.open("GET", url, false /* async = false */);                    xhr.send(null);                    data = xhr.responseText;                }                /* globalEval(data); */                appendScript(url, data, oHead);            }        };    } (eval));    /**     * global functions:     */    window.UTIL.ERRINDEX = -1;    window.UTIL.DEBUG = DEBUG;    window.UTIL.log = log;    window.UTIL.importScripts = importScripts;}(window));

最后我总结一下, 为了实现类似C/java的文件引用包含, 我写了一个prerequisite.js, 它提供全局的函数UTIL.importScripts(), prerequisite.js唯一的要求就是必须在页面的其他js加载前加载. 以后我们就可以在我们的js里使用UTIL.importScripts() 包含任何你想要包含的js文件. 因为我们必须要保证包含的文件必须被加载, 因此UTIL.importScripts()采用的是同步模式.


好了, 大胆的使用这个技巧吧, 你就可以实现真正的code behind. 总共就3步:

1) 写一个A.html, 并将prerequisite.js作为第一个引入的js文件;

2) 写自己的B.js库, 需要引用其他C.js, D.js, E.js文件的时候,就在B.js文件头部使用

UTIL.importScripts("/path/C.js", "/path/D.js", "/path/E.js");

3) path是C,D,E.js相对于B.js的路径.








读书人网 >C++

热点推荐