根据配置文件加载js依赖模块


Posted in Javascript onDecember 29, 2014

要求:

根据下面的配置文件

module=[

{'name':'jquery','src':'/js/lib/jquery-1.8.3.js'},

{'name':'swfobject','src':'/js/utils/swfobject.js'},

{'name':'fancybox','src':'/js/jquery/jquery.fancybox.js','require':['jquery']},

{'name':'uploadify','src':'/js/utils/uploadify.js','require':['swfobject']},

{'name':'jqform','src':'/js/jquery/jquery.form.js','require':['jquery']},

{'name':'register','src':'/js/page/reg.js','require':['jqform']},

{'name':'login','src':'/js/page/login.js','require':['fancybox','jqform']},

{'name':'upload','src':'/js/page/upload.js','require':['fancybox','jqform','uploadify']}

]

写一个函数

def getfiles(name)

返回 加载某个name指定的页面,要加载的js文件列表,有依赖的要先加载

小菜解法

    此题粗看起来很简单,实则不然。

     难点在于依赖模块的加载时机。假如有这样的依赖关系:A-B&C、B-C,A模块依赖B模块和C模块,同时B模块又依赖了C模块,总不能让C加载两次吧!

     小菜给出的这个解法,只是一个思路,肯定有比这更好的算法,小菜觉得可以用二叉树之类的算法解决,但小菜不会呀~~~

     此算法没有考虑循环依赖的情景。

     代码如下:

 /**

  * 不考虑循环依赖

  * @type {Function}

  */

 var loadModule = (function(){

     /**

      * 业务逻辑封装

      * @type {{chainHead: {}, chainCurrent: {}, srcCache: {}, main: main, load: load, findModule: findModule}}

      */

     var logics = {

         chainHead: {},     //链表头

         chainCurrent: {},  //链表当前节点

         srcCache: {},      //module src 缓存

         /**

          * 对外接口

          * @param modules  配置对象

          * @param name  模块名称

          * @returns {Array} 依赖模块列表,按照加载先后顺序排列

          */

         main: function(modules, name){

             var nameArray = [],  //模块名称列表

                 srcArray = [],   //依赖模块列表

                 nameStr = "",    //模块名称字符串集

                 repeatRegex = /(^| )([\w]+ ).*\2/,  //模块名称去重正则

                 i = 0;

             //粗略加载所有依赖模块

             this.load(modules, name)

             //构造模块名称字符串集

             this.chainCurrent = this.chainHead;

             while(this.chainCurrent.next){

                 nameArray.push(this.chainCurrent.name);

                 this.chainCurrent = this.chainCurrent.next;

             }

             nameStr = nameArray.join(" ") + " ";  //统一标准,末尾补一个空格

             //依赖模块去重

             while(repeatRegex.exec(nameStr)){

                 nameStr = nameStr.replace(repeatRegex, function(g0, g1, g2){

                     return g0.substring(0, (g0.length - g2.length));

                 });

             }

             nameStr = nameStr.substring(0, (nameStr.length - 1));  //去掉补充的多余空格

             //依赖模块名称转换为模块路径

             nameArray = nameStr.split(" ");

             for(i = 0; i < nameArray.length; i++){

                 srcArray.push(this.srcCache[nameArray[i]]);

             }

             return srcArray;

         },

         /**

          * 递归加载模块

          * @param modules  配置对象

          * @param name  模块名称

          */

         load: function(modules, name){

             var node = {},

                 module = this.findModule.call(modules, "name", name),

                 i = 0;

             //判断模块是否存在

             if(!module){

                 throw Error("依赖模块 " + name +" 未找到");

             }

             //构造模块依赖链表

             node.name = name;

 //            node.src = module.src;

             this.srcCache[name] = module.src;

             node.next = this.chainHead;

             this.chainHead = node;

             //递归依赖

             if(module.require && module.require.length){

                 for(i = 0;i < module.require.length; i++){

                     this.load(modules, module.require[i]);

                 }

             }

         },

         /**

          * 根据指定属性名称和属性值查找模块

          * @param name  属性名称

          * @param value  属性值

          * @returns {*}

          */

         findModule: function(name, value){

             var array = this,

                 item = {},

                 i = 0;

             //遍历模块

             for(i = 0; i < array.length; i++){

                 item = array[i];

                 //获取指定模块

                 if(item && item[name] === value){

                     return item;

                 }

             }

             //找不到返回null

             return null;

         }

     };

     //暴露对外接口

     return function(){

         return logics.main.apply(logics, arguments);

     };

 }());

 /**

  * Test Usecase

  * @type {*[]}

  */

 var modules=[

     {'name':'jquery','src':'/js/lib/jquery-1.8.3.js'},

     {'name':'swfobject','src':'/js/utils/swfobject.js'},

     {'name':'fancybox','src':'/js/jquery/jquery.fancybox.js','require':['jquery']},

     {'name':'uploadify','src':'/js/utils/uploadify.js','require':['swfobject']},

     {'name':'jqform','src':'/js/jquery/jquery.form.js','require':['jquery']},

     {'name':'register','src':'/js/page/reg.js','require':['jqform']},

     {'name':'login','src':'/js/page/login.js','require':['fancybox','jqform']},

     {'name':'upload','src':'/js/page/upload.js','require':['fancybox','jqform','login','uploadify']}

 ];

 console.log(loadModule(modules, "upload"));
Javascript 相关文章推荐
IE中jscript/javascript的条件编译
Sep 07 Javascript
msn上的tab功能Firefox对childNodes处理的一个BUG
Jan 21 Javascript
javascript web对话框与弹出窗口
Feb 22 Javascript
JS 添加网页桌面快捷方式的代码详细整理
Dec 27 Javascript
推荐4个原生javascript常用的函数
Jan 12 Javascript
关于两个jQuery(js)特效冲突的bug的解决办法
Sep 04 Javascript
HTML中setCapture、releaseCapture 使用方法浅析
Sep 25 Javascript
jQuery插件ajaxFileUpload异步上传文件
Oct 19 Javascript
Bootstrap table使用方法总结
May 10 Javascript
React复制到剪贴板的示例代码
Aug 22 Javascript
微信小程序使用video组件播放视频功能示例【附源码下载】
Dec 08 Javascript
微信小程序使用slider设置数据值及switch开关组件功能【附源码下载】
Dec 09 Javascript
JavaScript中的console.dir()函数介绍
Dec 29 #Javascript
JavaScript中的console.group()函数详细介绍
Dec 29 #Javascript
小米公司JavaScript面试题
Dec 29 #Javascript
谷歌浏览器调试JavaScript小技巧
Dec 29 #Javascript
JavaScript中的console.trace()函数介绍
Dec 29 #Javascript
JavaScript中的console.profile()函数详细介绍
Dec 29 #Javascript
jQuery中element选择器用法实例
Dec 29 #Javascript
You might like
Linux下ZendOptimizer的安装与配置方法
2007/04/12 PHP
优化JavaScript脚本的性能的几个注意事项
2006/12/22 Javascript
兼容ie、firefox的图片自动缩放的css跟js代码分享
2013/08/12 Javascript
jQuery filter函数使用方法
2014/05/19 Javascript
JavaScript中的null和undefined区别介绍
2015/01/01 Javascript
jQuery简单几行代码实现tab切换
2015/03/10 Javascript
jquery实现移动端点击图片查看大图特效
2020/09/11 Javascript
JavaScript每天必学之数组和对象部分
2016/09/17 Javascript
JavaScript 实现的checkbox经典实例分享
2016/10/16 Javascript
JavaScript和jQuery制作光棒效果
2017/02/24 Javascript
随机生成10个不重复的0-100的数字(实例讲解)
2017/08/16 Javascript
zTree异步加载展开第一级节点的实现方法
2017/09/05 Javascript
原生js的ajax和解决跨域的jsonp(实例讲解)
2017/10/16 Javascript
jquery.pager.js实现分页效果
2019/07/29 jQuery
vue-router结合vuex实现用户权限控制功能
2019/11/14 Javascript
JavaScript WeakMap使用详解
2021/02/05 Javascript
vue实现桌面向网页拖动文件的示例代码(可显示图片/音频/视频)
2021/03/01 Vue.js
Python中Collection的使用小技巧
2014/08/18 Python
Python实现图像几何变换
2015/07/06 Python
Python正则捕获操作示例
2017/08/19 Python
python编程羊车门问题代码示例
2017/10/25 Python
python实现接口并发测试脚本
2019/06/25 Python
ipython jupyter notebook中显示图像和数学公式实例
2020/04/15 Python
keras模型保存为tensorflow的二进制模型方式
2020/05/25 Python
python logging模块的使用
2020/09/07 Python
如何利用Python 进行边缘检测
2020/10/14 Python
浅谈pc和移动端的响应式的使用
2019/01/03 HTML / CSS
AHAVA美国官方网站:死海海泥护肤品牌
2016/10/18 全球购物
Ryderwear澳洲官网:澳大利亚高端健身训练装备品牌
2018/09/18 全球购物
全球性的在线鞋类品牌:Public Desire
2019/04/03 全球购物
人事行政主管岗位职责
2013/12/22 职场文书
部队万能检讨书
2014/02/20 职场文书
初中新生军训方案
2014/05/13 职场文书
优秀研究生主要事迹
2014/06/03 职场文书
大一新生期末自我评价
2014/09/12 职场文书
Python使用scapy模块发包收包
2021/05/07 Python