在做OA、MIS、ERP等信息管理类的项目,经常会遇到引用很多js文件,这就需要用到动态加载、缓存、更新以及复用等技术,下面我们来讨论下

使用范围:

OA、MIS、ERP等信息管理类的项目,暂时不考虑网站。

遇到的问题:

完成一个项目,往往需要引用很多js文件,比如jQuery.js、easyUI等。还有自己写的一些列js文件,那么这些文件如何方便的加载,如果文件有变化如何才能让客户端及时更新缓存?如果能够提高点运行效率,那就更好了。

目标:

1、  可以方便的引用js文件。

2、  尽量使用各种缓存,避免频繁从服务器读取文件。

3、  如果js文件有更新或者增加、几个js文件,需要客户端能够自动、立刻更新。

4、  Js文件的复用。

页面结构:

一般OA、MIS这一类的项目,大多采用frameset或者iframe的方式来实现,这样就有了父页和子页的概念。我们可以利用这一点来做做文章。

网页可以分为三块:外壳、首页、标签、数据列表、表单(添加、修改)。因为这里要说的加载js的方法,需要利用这种页面结构,也正是因为这个原因,所以暂时不支持网站。

看这个图有点眼熟吧。恩,就是这种结构。

正文

现在做web版的应用,越来越依赖各种js了,第三方的jQuery、easyUI、my97等,还有自己写的各种js。要实现的功能越来越多,需要使用的js也越来越多,js文件的修改也很频繁。于是就出现了许多问题,比如每个页面都要写一大堆<script src=””>。这个也太麻烦了吧,增加一个新的js文件,需要改多少页面?js文件更新了如何让客户端也立即更新?如何让客户端更快的加载js。有的Js文件还有依赖关系,如何确保加载顺序?本文内容就是分享一下我的解决方案。

动态加载

在页面里使用<script>加载js,显然很麻烦,那么怎么办呢?想来想去还是用动态加载的方法来解决。在网上也搜索了一番,有很多种方法,有自己手动写的,有整理成框架的(比如seejs)。有的时候还是感觉自己弄一个更加的应手,所以打算自己写一套。

如何动态加载呢?使用jQuery提供的方法吗?这个倒是可以,但是页面必须引用jQuery和我写的加载js文件的js。也就是说一个页面要写两个<script>,这个就麻烦了。能写一个,就一定不要写两个,虽然只是多了一个,但是多了这么一个就真的很麻烦。所以决定自己手写一个动态加载的小方法。

不会写怎么办呢?百度大婶来帮忙吧。各种搜呀,终于找到了一个比较的方法,恩就用这个了。


/*实现动态加载js的函数,来自于互联网,做了一点修改,可以兼容IE10 */
var loadscript =
{
  $$: function(id) { return document.getElementById(id); },
  tag: function(element) { return document.getElementsByTagName(element); },
  ce: function(element) { return document.createElement(element); },
  js: function(url, callback) {
  var s = loadscript.ce('script');
  s.type = "text/javascript";
  s.src = url;
  if (document.documentMode == 10 || document.documentMode == 9) {
  s.onerror = s.onload = loaded;
  } else {
  s.onreadystatechange = ready;
  s.onerror = s.onload = loaded;
  }
  loadscript.tag('head')[0].appendChild(s);

  function ready() { /*IE7.0/IE10.0*/
  if (s.readyState == 'loaded' || s.readyState == 'complete') {
  callback();
  }
  }

  function loaded() { /*chrome/IE10.0*/
  callback();
  }
  }
};

加载顺序

和新代码已经搞定了,下面就是如何加载其他js文件了,由于文件比较多,还有一定的依赖关系,想来想去还是弄个js文件的字典吧,然后做一个加载顺序,按照这个顺序来加载。

为了更稳定一点,决定采用一个一个加载的方式,即加载完一个js,然后在加载另一个js。这样就可以确保依赖关系。当然缺点是加载速度会比较慢。一般网页加载js是可以多个js文件一起下载的,这个速度就会比较快。

使用缓存

一般浏览器对于各种资源(比如网页、图片、js、css等)会有一个缓存,已经有了就不会再向服务器去下载了。看似很好,但是有两个问题:

  A、浏览器如何判断缓存的js文件是不是最新的?

  B、js文件更新了,如何强制浏览器更新?

浏览器是怎么判断的呢?具体步骤我也不太清楚,只是知道有一个步骤是要到服务器问问,我缓存的js文件是不是最新的,然后才能够确定本地的缓存是否是最新的,如果是最新的就不折腾了,如果不是再去下载最新的。就是说呢,即使客户端已经有了js文件的缓存,但是浏览器要确认一下是否最新,还是会跑到服务器去问问。这个,折腾呀。当然一般情况下,这个过程会很快,但是有时候这个过程会很慢。

所以呢,还是尽量避免加载js的好。于是就引出来的“js文件的复用”。

更新js文件

Js文件更新了,但是浏览器却还在用以前的js文件,因为有缓存了,而且还固执的认为缓存的js文件就是最新的,哎咋办呀?

最简单的方法就是在加载js的时候,后面跟一个版本号,有更新了,就版本号+1。比如 xxx.js?v=1。Js文件更新后就是 xxx.js?v=2。这样js就肯定会被更新了。

看起来似乎很简单,但是这个版本号如何加上去?版本号本身又如何更新呢?

复用

这个就要先看看上面那个图了,就是页面结构,有一个外壳页(或者首页),我们叫做父页。里面还有若干个iframe加载的页面,我们加做子页。

一般的做法是,父页里加载jQuery.js,然后子页里也要加载jQuery.js。当然当子页在加载jQuery.js的时候,直接从缓存里面提取,一般不会再去折腾服务器了。

但是,既然父页里面已经加载了,子页为啥还要再加载一次?直接用父页里加载好的行不行呢?到网上搜了一下,似乎没有人这么做。也许是我太另类了吧,我就是想实现这个方法。优点就是,所有的js文件都在父页里加载,子页直接使用父页里加载好的js,这样子页就不需要在折腾js文件了。这样效率也可以更高一些,毕竟即使用缓存里加载,也是要判断一下,然后在做个加载的动作,还是会有一点点损耗,js文件越多也就越明显。

那么如何实现呢,想想似乎很简单。

父页里使用jQuery

Var aa = $('div');  //找到父页里的所有div

子页里是不是可以这么做?

Var  bb = top.$ ('div') ; //能够找到div,但是不是子页的div而是父页里的div。

咋回事呢?原因就在于搜索范围。jQuery是有三个参数的,我们平时只用了第一个,后面的就被忽略了。那么第二个参数是啥呢?就是搜索范围。没有指定的时候,jQuery会在哪里搜索呢?加载jQuery的页面里面搜索,而不是调用$的页面里搜索。

解决方法也很简单,加个参数就好了

Var  bb = top.$ ('div',document) ; //指定搜索范围:子页的document

等等,这个似乎很烦人,我们在写脚本的时候,还要考虑一下,这个脚本是在父页里执行还是在子页里执行吗?

好了,做一个简单的封装,避免这个麻烦。子页里写个函数


function $ (p1){
return top.$ (p1,document);
}

 

好了,大功告成了吗?当然没有!预知后事如何,请听下回分解。

ps:下集预告。就是具体的实现代码,还有一些思路和想法,不知道大家还有啥想知道的没,有的话,欢迎在下面回复一下。谢谢先。


 

最新资讯
滴滴启动国庆出行安全部署 程维:安全发展观是必修课

滴滴启动国庆出行安全

滴滴出行CEO、安委会主任程维在会上表示,今年是滴滴安
爱回收E+轮融资超1亿美元 二手行业难做全品类

爱回收E+轮融资超1亿

陈雪峰谈到并未做全品类的原因时认为,二手行业不存在全
中通宣布将香港上市发行价定为每股218港元 下周二挂牌

中通宣布将香港上市发

中通快递(NYSE:ZTO)今晚宣布,将香港二次上市的发行价定为
微信支付正计划加码存款市场 相关功能正处测试阶段

微信支付正计划加码存

9月22日消息,微信支付正计划加码存款市场。记者近期注
比亚迪据称商谈向戴姆勒供应电动汽车芯片

比亚迪据称商谈向戴姆

知情人士透露,沃伦·巴菲特支持的比亚迪正在与戴姆勒洽
强如BAT、TMD也难免栽跟头

强如BAT、TMD也难免栽

被视为中国互联网顶流的BAT、TMD,家家有本难念的经,发展
最新文章
详解Vue的ref特性的使用

详解Vue的ref特性的使

这篇文章主要介绍了详解Vue的ref特性的使用,文中通过
vue学习笔记之slot插槽基本用法实例分析

vue学习笔记之slot插

这篇文章主要介绍了vue学习笔记之slot插槽基本用法,结
vue跳转方式(打开新页面)及传参操作示例

vue跳转方式(打开新页

这篇文章主要介绍了vue跳转方式(打开新页面)及传参操作,
vue学习笔记之过滤器的基本使用方法实例分析

vue学习笔记之过滤器

这篇文章主要介绍了vue学习笔记之过滤器的基本使用方
js获取本日、本周、本月的时间代码

js获取本日、本周、本

本篇文章给大家分享的内容是利用js如何获取本日、本周
node crawler如何添加promise支持

node crawler如何添加

这篇文章主要介绍了node crawler如何添加promise支持,