JS 实现完美include载入实现代码


Posted in Javascript onAugust 05, 2010

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,这样就不会出现引用问题。

实现代码如下:

// 根据相对路径获取绝对路径 
function getPath(relativePath,absolutePath){ 
var reg = new RegExp("\\.\\./","g"); 
var uplayCount = 0; // 相对路径中返回上层的次数。 
var m = relativePath.match(reg); 
if(m) uplayCount = m.length; 
var lastIndex = absolutePath.length-1; 
for(var i=0;i<=uplayCount;i++){ 
lastIndex = absolutePath.lastIndexOf("/",lastIndex); 
} 
return absolutePath.substr(0,lastIndex+1) + relativePath.replace(reg,""); 
} 
function include(jssrc){ 
// 先获取当前a.js的src。a.js中调用include,直接获取最后1个script标签就是a.js的引用。 
var scripts = document.getElementsByTagName("script"); 
var lastScript = scripts[scripts.length-1]; 
var src = lastScript.src; 
if(src.indexOf("http://")!=0 && src.indexOf("/") !=0){ 
// a.js使用相对路径,先替换成绝对路径 
var url = location.href; 
var index = url.indexOf("?"); 
if(index != -1){ 
url = url.substring(0, index-1); 
} 
src = getPath(src,url); 
} 
var jssrcs = jssrc.split("|"); // 可以include多个js,用|隔开 
for(var i=0;i<jssrcs.length;i++){ 
// 使用juqery的同步ajax加载js. 
// 使用document.write 动态添加的js会在当前js的后面,可能会有js引用问题 
// 动态创建script脚本,是非阻塞下载,也会出现引用问题 
$.ajax({type:'GET',url:getPath(jssrc,src),async:false,dataType:'script'}); 
} 
}

在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文件的内容。
[作者]:BearRui(AK-47)

Javascript 相关文章推荐
Prototype RegExp对象 学习
Jul 19 Javascript
JavaScript之appendChild、insertBefore和insertAfter使用说明
Dec 30 Javascript
Javascript代码在页面加载时的执行顺序介绍
May 03 Javascript
jquery基础教程之deferred对象使用方法
Jan 22 Javascript
js的toLowerCase方法用法实例
Jan 27 Javascript
分享两个手机访问pc网站自动跳转手机端网站代码
Dec 24 Javascript
基于Bootstrap+jQuery.validate实现表单验证
May 30 Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
Sep 05 Javascript
原生JS中slice()方法和splice()区别
Mar 06 Javascript
vue使用better-scroll实现滑动以及左右联动
Jun 30 Javascript
vue-列表下详情的展开与折叠案例
Jul 28 Javascript
利用js实现简易红绿灯
Oct 15 Javascript
使用ExtJS技术实现的拖动树结点
Aug 05 #Javascript
JavaScript 获取当前时间戳的代码
Aug 05 #Javascript
firefox事件处理之自动查找event的函数(用于onclick=foo())
Aug 05 #Javascript
Js获取事件对象代码
Aug 05 #Javascript
zeroclipboard复制到剪切板的flash
Aug 04 #Javascript
jQuery Study Notes学习笔记 (二)
Aug 04 #Javascript
JQuery Study Notes 学习笔记(一)
Aug 04 #Javascript
You might like
实现分十页分向前十页向后十页的处理
2006/10/09 PHP
一些常用的php简单命令代码集锦
2007/09/24 PHP
php中随机显示图片的函数代码
2011/06/23 PHP
php中url传递中文字符,特殊危险字符的解决方法
2013/08/17 PHP
PHP实现的增强性mhash函数
2015/05/27 PHP
php模拟post上传图片实现代码
2016/06/24 PHP
PHP中加速、缓存扩展的区别和作用详解(eAccelerator、memcached、xcache、APC )
2016/07/09 PHP
PHP7内核CGI与FastCGI详解
2019/04/14 PHP
Div Select挡住的解决办法
2008/08/07 Javascript
jquery select(列表)的操作(取值/赋值)
2011/03/16 Javascript
js使用栈来实现10进制转8进制与取除数及余数
2014/06/11 Javascript
原生javascript实现拖动元素示例代码
2014/09/01 Javascript
JS实现的仿东京商城菜单、仿Win右键菜单及仿淘宝TAB特效合集
2015/09/28 Javascript
jQuery实现彩带延伸效果的网页加载条loading动画
2015/10/29 Javascript
JavaScript如何动态创建table表格
2020/08/02 Javascript
js生成随机数的过程解析
2015/11/24 Javascript
jquery读写cookie操作实例分析
2015/12/24 Javascript
全面解析Bootstrap中tab(选项卡)的使用方法
2016/06/06 Javascript
JS生成不重复的随机数组的简单实例
2016/07/10 Javascript
解决jquery的ajax调取后端数据成功却渲染失败的问题
2018/08/08 jQuery
vue 实现模糊检索并根据其他字符的首字母顺序排列
2019/09/19 Javascript
微信小程序订阅消息(java后端实现)开发
2020/06/01 Javascript
vue实现两个组件之间数据共享和修改操作
2020/11/12 Javascript
如何解决django配置settings时遇到Could not import settings 'conf.local'
2014/11/18 Python
Python实现的爬取豆瓣电影信息功能案例
2019/09/15 Python
python和go语言的区别是什么
2020/07/20 Python
The Beach People美国:澳洲海滨奢华品牌
2018/07/05 全球购物
ManoMano英国:欧洲第一家专注于DIY和园艺市场的电商平台
2020/03/12 全球购物
在Java开发中如何选择使用哪种集合类
2016/08/09 面试题
大学生四年生活自我鉴定
2013/11/21 职场文书
大学生简短的自我评价分享
2014/02/20 职场文书
毕业典礼主持词大全
2014/03/26 职场文书
学习雷锋演讲稿
2014/05/10 职场文书
如何判断微信付款码和支付宝付款码
2021/04/01 PHP
数据分析数据库ClickHouse在大数据领域应用实践
2022/04/03 MySQL
新的CSS 伪类函数 :is() 和 :where()示例详解
2022/08/05 HTML / CSS