js为什么需要include?让我们想想这样1个场景,a.js 需要用到1个公用的common.js,当然你可以在用到a.js的页面使用<script src="common.js">,但假设有5个页面用到了a.js,你是不是要写5遍<script。而且要是以后a.js 又需要引用common2.js,你是不是又的修改5个页面了?

已有js include的一些问题

  在写这个之前在网上搜索了些资料,发现以前写的include都存在2个问题,这也是include需要解决的比较重要的2个问题。

  1、相对路径的问题:  在a.js中使用include("../js/common.js");  include 函数中肯定是使用相对路径,是相对a.js的路径。而a.js在html中使用<script>嵌入有可能是相对路径,有可能是绝对路径。  include函数如何才能真正确定common.js的绝对路径,或者是相对html的相对路径。网上一些为了解决这个问题,还需要加一些js变量,不方便。

  2、引用的问题。  网上include函数的实现几乎都是使用下面2种方式插入common.js

      document.write("<script src='" + .. + "></script>")

    或者

      var s = document.createElement("script");

      s.src = ...;

      head.insertAfter(s,...);

    document.write 输出的脚本会在a.js后面加载,而createElement("script")创建的脚本是非阻塞加载。  所以如果在common.js加载完毕之前,a.js中调用了common.js的函数就会报错。

实现

  解决上面2个问题,就可以实现js include。

  第1个问题,我的方法是先获取到a.js在html中的绝对路径(如果是相对路径,就转为绝对路径),然后再把common.js的路径转为绝对路径。

  第2个问题,采用同步的ajax来请求common.js,这样就不会出现引用问题。

  实现代码如下:

view sourceprint?01 // 根据相对路径获取绝对路径

02 function getPath(relativePath,absolutePath){

03     var reg = new RegExp("//.//./","g");

04     var uplayCount = 0;     // 相对路径中返回上层的次数。

05     var m = relativePath.match(reg);

06     if(m) uplayCount = m.length;

07

08     var lastIndex = absolutePath.length-1;

09     for(var i=0;i<=uplayCount;i++){

10         lastIndex = absolutePath.lastIndexOf("/",lastIndex);

11     }

12     return absolutePath.substr(0,lastIndex+1) + relativePath.replace(reg,"");

13 }

14

15 function include(jssrc){

16     // 先获取当前a.js的src。a.js中调用include,直接获取最后1个script标签就是a.js的引用。

17     var scripts = document.getElementsByTagName("script");

18     var lastScript = scripts[scripts.length-1];

19     var src = lastScript.src;

20     if(src.indexOf("http://")!=0 && src.indexOf("/") !=0){

21         // a.js使用相对路径,先替换成绝对路径

22         var url = location.href;

23         var index = url.indexOf("?");

24         if(index != -1){

25             url = url.substring(0, index-1);

26         }

27

28         src = getPath(src,url);

29     }

30     var jssrcs = jssrc.split("|");  // 可以include多个js,用|隔开

31     for(var i=0;i<jssrcs.length;i++){

32         // 使用juqery的同步ajax加载js.

33         // 使用document.write 动态添加的js会在当前js的后面,可能会有js引用问题

34         // 动态创建script脚本,是非阻塞下载,也会出现引用问题

35         $.ajax({type:'GET',url:getPath(jssrc,src),async:false,dataType:'script'});

36     }

37 }

  在a.js中直接使用 include("../js/common.js");

多请求的问题

  使用上面的include看上去挺爽的,不过却带来另外1个严重的问题,就是多发送了1个ajax的请求。

  我们常常为了WEB性能,而合并js,减少请求。但使用include后却偏偏多了请求。如果这个问题不解决,相信很多人都不会在正式产品中使用include的了,除非是局域网产品。

  如何解决这个多请求的问题,我也思考很久,最后觉的单单使用客户端js是没办法解决了。所以就想到了使用服务端代码来解决

  还记的我之前有文章介绍 "js、css的合并、压缩、缓存管理"的时候,就通过服务器端代码在程序启动时候去合并js。

  所以我把include多请求的解决方案也加到里面去。就是在程序启动的时候去查找所有的js,发现有使用include的就把include中common.js的源代码替换该include函数。这样a.js中在运行的时候就没有include函数,而是真真包含了common.js的内容的js文件

后语

  丫的。说到最后,怎么又把所有的include都替换掉了,哪之前说的那么多不白说了。

  个人觉得,每个产品都应该要区分开发环境和产品环境(一般通过配置文件进行区分),在开发环境应该以开发效率为首要,而产品环境则以性能为首。所以这里的inlcude就应该要区分对待,在开发环境中使用js include来提高开发和维护效率,而在产品环境中则自动把所有include替换成真真的js文件的内容。

关注技术文章飞秋:http://www.freeeim.com/,24小时专业转载。

【飞秋】JS 实现完美include相关推荐

  1. 【飞秋】记一次“偷盗”别人的CSS和Js

    今天下午,公司网站要求改版,需要做一个和51Job类似的职位选择和行业类别选择JS特效,偏偏这个任务落到了我这个最不懂Js的人的手上!苍天.大地-- 别提我自己写了,先是上网一搜,哎,很多例子嘛,而且 ...

  2. 这说明什么?【转载】早点长大的飞秋2013

    [转载]早点长大的飞秋 作者:       i_like_cpp        -       日期:2013-05-07     浏览 0 次 今天的早点长大的飞秋,早点长大,为了早点成为神奇的土地 ...

  3. 红衣大炮的飞秋实现原理

    摘要:飞秋实现原理 2012年07月12日,能使对方将领的大部分技能无效化,技能为束缚和屏蔽,夫妻,他被奉为锻造的庇护神,完美的好友,帮助他击败了泰坦帕耳莫斯,现在活跃与天空之城的他相当乐意为那些刚刚 ...

  4. 飞秋官方下载 这个程序很不错

    我上班第一天我的老板让我做的第一件事,看两篇文章,飞秋局域网聊天随想,我不是天生的 飞秋官方下载,也并非天生就喜欢电脑,上高中时也没有想过将来会当飞秋局域网聊天,接触电脑纯属偶然--小时候的一个好朋友 ...

  5. 飞秋(FeiQ)仍然痛感hongjin2的计算机基础理论不好

    用手机随时随地轻松炒股! 某些股割肉出逃肯定会后悔 突发暴涨很可能不期而至 股民福音:套牢股票有救了! 收录时间不长,页数不多,土豆网电视剧JS调用,但是世界排名很高的,没有必要换.最后,外部土豆网电 ...

  6. 飞秋文件传输模拟实现代码

    最近一直在研究基于WINSOCK的文件传输,文件传输时会出现各种各样的情况处理起来其实也挺麻烦的这里不一一说明,大家看代码吧,这是最新版 飞秋 http://www.freeeim.com/ 的代码, ...

  7. 【飞秋】位运算与组合搜索(二)

    这篇文章接着讲怎样高效地遍历所有的组合.同样,假定全集的大小不大于机器字长,计算模型为 word-RAM,即诸如 +, –, *, /, %, &, |, >>, << ...

  8. 【飞秋】进一步完善 -- GEF创建助手工具条

    昨天讨论了在图形元素上显示工具条的方法,应该说工作的还不是很完美,因为在选定了创建Connection的工具后,并不能像使用palette那样,在鼠标移动的过程中,有一个连接动态跟随,当鼠标释放后,如 ...

  9. 【飞秋】Android开发——NDK开发入门

    注:本文并非原创,参考了几位前辈的文章,本文只是稍作整理. 参考1:Eclipse配置NDK_R4开发环境(集成Cygwin .CDT) 分别介绍了在window和linux下配置eclipse自动化 ...

最新文章

  1. 【CCNP考试】2010-01-31-北京-845(PASS)
  2. 英特尔的指令集体系结构_对标英特尔的RISC-V大有可为,CPU三分天下格局可期
  3. C++ new delete操作符
  4. 【PAT甲级 环最短距离】1046 Shortest Distance (20 分) Java、C++
  5. webservice 服务器无法处理请求_Message Queue与WebService比较
  6. 中国最大照明企业贱卖给外资 创始人遭下狱 刘强东怒斥:有些人没有道德底线!...
  7. 央视牵手搜狗,AI合成主播为3·15晚会预热
  8. 对话短文本语义匹配-冠军代码
  9. AI金融知识自学偏量化方向-了解不同类型的机器学习2
  10. jQuery 学习笔记 选择元素
  11. 恒生杭州历年软件测试笔试题,【恒生电子软件测试面试】首先做一个笔试题,然...-看准网...
  12. MySQL中增删改查的例子
  13. U盘空间明明够大,为什么却放不进去文件
  14. 【ssh连接】解决网络突然断线进程执行中止问题
  15. 软件体系结构描述与建模
  16. 石墨烯之父”、诺贝尔物理学奖得主:造访江西理工大学
  17. [EOS源码分析]7.EOS智能合约开发实践之合约调用合约(inline action)
  18. lower_bound()函数和upper_bound函数
  19. linux egg,Ubuntu下egg文件的安装与制作
  20. android10全面屏手势 操作图,全面屏手势浪潮来临?安卓Q测试版新发现,手势操作十分便捷...

热门文章

  1. elasticsearch基本查询二(英文分词)term和terms查询
  2. SpringCloud Ribbon实战(二)
  3. 第五部分 自定义的Calendar接口示例
  4. 互联网日报 | 美团市值突破万亿港元;北京恢复二级响应;滴滴货运23日上线;微信开放MCN入驻...
  5. 两数之和(Leetcode第1题)
  6. 界面设计方法 (1) — 4. 看板功能的设计
  7. 第三届“空间信息网络”学术论坛诚邀您的参加
  8. 大数高精加减乘除(洛谷P1601、P2142、P1303、P1480题题解,Java语言描述)
  9. 【CSS3】将截断的文字可选的显示出来
  10. 【Python】Matplotlib分层绘制投影柱状图