zoukankan      html  css  js  c++  java
  • 像C++一样写JavaScript

    像C++一样写JavaScript

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

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1">
      <title>欢迎使用ligerUI</title> 
    
      <link href="lib/ligerUI/skins/Aqua/css/ligerui-all.css" rel="stylesheet" type="text/css" />
      <link href="lib/ligerUI/skins/Gray/css/all.css" rel="stylesheet" type="text/css" />
      <link href="lib/css/common.css" rel="stylesheet" type="text/css" />  
      <link href="lib/css/index.css" rel="stylesheet" type="text/css" />
    
      <script src="lib/jquery/jquery-1.5.2.min.js" type="text/javascript"></script>
      <script src="lib/ligerUI/js/ligerui.min.js" type="text/javascript"></script>  
      <script src="lib/ligerUI/js/plugins/ligerTab.js" type="text/javascript"></script>
      <script src="lib/ligerUI/js/plugins/ligerLayout.js" type="text/javascript"></script>
    
      <script src="lib/js/common.js" type="text/javascript"></script>
      <script src="lib/js/LG.js" type="text/javascript"></script>
      <script src="lib/js/login.js" type="text/javascript"></script>
    
      <script src="/lib/jquery-validation/jquery.validate.min.js" type="text/javascript"></script> 
      <script src="/lib/jquery-validation/jquery.metadata.js" type="text/javascript"></script>
      <script src="/lib/jquery-validation/messages_cn.js" type="text/javascript"></script>
    
      <script src="lib/js/changepassword.js" type="text/javascript"></script>
      <script src="lib/ligerUI/js/plugins/ligerForm.js" type="text/javascript"></script>
    
      <!-- settings menus -->
      <script src="index.html.js" type="text/javascript"></script>
    </head>
    <body>
    ...
    </body>
    </html> 


    可以看到, 为了使用某个第3方库(这里是ligerUI), 我们不得不把所有需要的js文件在html里引入进来. 下面修改上面的index.html, 看看新的写法可以给我们带来什么惊喜:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1">
        <title>欢迎使用ligerUI</title>
    
        <link href="lib/ligerUI/skins/Aqua/css/ligerui-all.css" rel="stylesheet" type="text/css" />
        <link href="lib/ligerUI/skins/Gray/css/all.css" rel="stylesheet" type="text/css" />
        <link href="lib/css/common.css" rel="stylesheet" type="text/css" />
        <link href="lib/css/index.css" rel="stylesheet" type="text/css" />
    
        <script src="lib/prerequisite.js" type="text/javascript"></script>
        <script src="index.html.js" type="text/javascript"></script>
    </head>
    <body>
    ...
    </body>
    </html>
    

    是不是简洁多了, 这个写法的关键是我们必须在引用任何js之前引入一个全局的API文件, 这里是prerequisite.js, 然后就可以引入自己的js文件, 这里是index.html.js, 在自己的js文件里引入所有我们需要的第3方库文件(如ligerUI). 下面我们看看index.html.js这个文件里作了什么:

    /**
     * index.html.js
     * version: 0.0.1
     */
    UTIL.importScripts(
        "lib/jquery/jquery-1.5.2.min.js",
        "lib/ligerUI/js/ligerui.min.js",
        "lib/js/common.js",
        "lib/js/LG.js",
        "lib/js/login.js",
        "lib/jquery-validation/jquery.validate.min.js",
        "lib/jquery-validation/jquery.metadata.js",
        "lib/jquery-validation/messages_cn.js",
        "lib/js/changepassword.js"
    );
    
    
    /* 下面是业务代码, 和文件包含没关系 */
    (function (window, undefined) {
        "use strict";
    
        
        /**
         * public interfaces
         */
    
    }(window));
    


    是不是很神奇呢, 这个和C/C++/java很像啦. UTIL.importScripts(...) 这个函数帮我们做了一切事情, 它是在 prerequisite.js 中定义的, 那么最后就是prerequisite.js文件:

    /**
     * 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*base64s*[;,]/.test(meta)) {
                            data=atob(data);
                        }
    
                        if (/;s*charset=[uU][tT][fF]-?8s*[;,]/.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的路径.

     

  • 相关阅读:
    DeepEarth更新到Silverlight 4了
    Silverlight & Blend动画设计系列八:拖放(DragDrop)操作与拖放行为(DragBehavior)
    VS2010之vb.net:细节决定成败
    iVIEW: An Intelligent Video over InternEt and Wireless Access System
    Tianya Doc
    治疗咳嗽
    一个 研究 可视化的个人博客
    Windows自启动方式完全总结
    JAVA连接DB2
    JSP 与 Discuz整合
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3293970.html
Copyright © 2011-2022 走看看