根据配置文件加载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 相关文章推荐
js下关于onmouseout、事件冒泡的问题经验小结
Dec 09 Javascript
js 异步操作回调函数如何控制执行顺序
Dec 24 Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
Feb 13 Javascript
原生js制作简单的数字键盘
Apr 24 Javascript
jQuery旋转木马式幻灯片轮播特效
Dec 04 Javascript
基于JavaScript判断浏览器到底是关闭还是刷新(超准确)
Feb 01 Javascript
浅谈javascript的call()、apply()、bind()的用法
Feb 21 Javascript
jquery把int类型转换成字符串类型的方法
Oct 07 Javascript
微信小程序 后台https域名绑定和免费的https证书申请详解
Nov 10 Javascript
jQuery实现自动调用和触发某个事件的方法
Nov 18 Javascript
教你用十行node.js代码读取docx的文本
Mar 08 Javascript
详解JSON Web Token 入门教程
Jul 30 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
PHP将整个网站生成HTML纯静态网页的方法总结
2012/02/05 PHP
php二维数组排序与默认自然排序的方法介绍
2013/04/27 PHP
php中使用Ajax时出现Error(c00ce56e)的详细解决方案
2014/11/03 PHP
PHP使用内置函数file_put_contents写入文件及追加内容的方法
2015/12/07 PHP
转一个日期输入控件,支持FF
2007/04/27 Javascript
基于jquery扩展漂亮的CheckBox(自己编写)
2013/11/19 Javascript
js对象的复制继承实例
2015/01/10 Javascript
Javascript实现Array和String互转换的方法
2015/12/21 Javascript
浅析JavaScript的几种Math函数,random(),ceil(),round(),floor()
2016/12/22 Javascript
浅谈Vue的基本应用
2016/12/27 Javascript
jQuery实现文章图片弹出放大效果
2017/04/06 jQuery
浅谈React前后端同构防止重复渲染
2018/01/05 Javascript
代码详解JS操作剪贴板
2018/02/11 Javascript
DatePickerDialog 自定义样式及使用全解
2019/07/09 Javascript
vue 实现Web端的定位功能 获取经纬度
2019/08/08 Javascript
Vuex模块化应用实践示例
2020/02/03 Javascript
详解JavaScript的this指向和绑定
2020/09/08 Javascript
Python生成pdf文件的方法
2014/08/04 Python
用实例解释Python中的继承和多态的概念
2015/04/27 Python
Python获取当前页面内所有链接的四种方法对比分析
2017/08/19 Python
python中使用正则表达式的连接符示例代码
2017/10/10 Python
Python基于贪心算法解决背包问题示例
2017/11/27 Python
python3获取两个日期之间所有日期,以及比较大小的实例
2018/04/08 Python
python实现Windows电脑定时关机
2018/06/20 Python
nginx+uwsgi+django环境搭建的方法步骤
2019/11/25 Python
pytorch 实现查看网络中的参数
2020/01/06 Python
Pycharm创建文件时自动生成文件头注释(自定义设置作者日期)
2020/11/24 Python
HTML5中语义化 b 和 i 标签
2008/10/17 HTML / CSS
美国羽绒床上用品第一品牌:Pacific Coast
2018/08/25 全球购物
英国玛莎百货美国官网:Marks & Spencer美国
2018/11/06 全球购物
英国领先的电动可调床制造商:Laybrook
2019/12/26 全球购物
安全生产网格化管理实施方案
2014/03/01 职场文书
党员反腐倡廉学习心得体会
2015/08/15 职场文书
2016年推广普通话宣传周活动总结
2016/04/06 职场文书
成人成长感言如何写?
2019/08/16 职场文书
CentOS7环境下MySQL8常用命令小结
2022/06/10 Servers