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 相关文章推荐
jquery控制listbox中项的移动并排序
Nov 12 Javascript
jQuery如何取id有.的值一般的方法是取不到的
Apr 18 Javascript
Flow之一个新的Javascript静态类型检查器
Dec 21 Javascript
jQuery基本选择器(实例及表单域value的获取方法)
May 20 Javascript
微信小程序  action-sheet详解及实例代码
Nov 09 Javascript
利用策略模式与装饰模式扩展JavaScript表单验证功能
Feb 14 Javascript
了解VUE的render函数的使用
Jun 08 Javascript
vue开发调试神器vue-devtools使用详解
Jul 13 Javascript
Vue自定义事件(详解)
Aug 19 Javascript
jQuery动态生成的元素绑定事件操作实例分析
May 04 jQuery
JavaScript模块管理的简单实现方式详解
Jun 15 Javascript
微信小程序使用echarts获取数据并生成折线图
Oct 16 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
PHP中的插件机制原理和实例
2014/07/08 PHP
php实现网站留言板功能
2015/11/04 PHP
Symfony2学习笔记之控制器用法详解
2016/03/17 PHP
php的常量和变量实例详解
2017/06/27 PHP
PHP实现的AES双向加密解密功能示例【128位】
2018/09/03 PHP
JS中剪贴板兼容性、判断复制成功或失败
2021/03/09 Javascript
Javascript的匿名函数小结
2009/12/31 Javascript
网页防止tab键的使用快速解决方法
2013/11/07 Javascript
jQuery实现简单下拉导航效果
2015/09/07 Javascript
学习JavaScript设计模式(接口)
2015/11/26 Javascript
javascript下使用Promise封装FileReader
2016/02/19 Javascript
jQuery ajax提交Form表单实例(附demo源码)
2016/04/06 Javascript
js组件SlotMachine实现图片切换效果制作抽奖系统
2016/04/17 Javascript
jquery精度计算代码 jquery指定精确小数位
2017/02/06 Javascript
详解angularJS自定义指令间的相互交互
2017/07/05 Javascript
vue页面跳转后返回原页面初始位置方法
2018/02/11 Javascript
webpack的CSS加载器的使用
2018/09/11 Javascript
对angularJs中ng-style动态改变样式的实例讲解
2018/09/30 Javascript
Angular刷新当前页面的实现方法
2018/11/21 Javascript
微信公众号H5支付接口调用方法
2019/01/10 Javascript
小程序中的箭头函数的具体使用
2020/06/19 Javascript
JavaScript文档加载模式以及元素获取
2020/07/28 Javascript
EXTJS7实现点击拖拉选择文本
2020/12/17 Javascript
使用Python爬了4400条淘宝商品数据,竟发现了这些“潜规则”
2018/03/23 Python
Python爬虫之正则表达式基本用法实例分析
2018/08/08 Python
django数据库自动重连的方法实例
2019/07/21 Python
安装2019Pycharm最新版本的教程详解
2019/10/22 Python
在django-xadmin中APScheduler的启动初始化实例
2019/11/15 Python
关于python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)
2020/10/19 Python
ktv周年庆活动方案
2014/08/18 职场文书
雨中的树观后感
2015/06/03 职场文书
趣味运动会口号
2015/12/24 职场文书
教师理论学习心得体会
2016/01/21 职场文书
民警忠诚教育心得体会
2016/01/23 职场文书
优秀员工演讲稿
2019/06/21 职场文书
vue实现Toast组件轻提示
2022/04/10 Vue.js