pace.js原理简介
简介:
不少童鞋可能都使用过pace.js:http://github.hubspot.com/pace/docs/welcome/
只要在页面上引入pace.js和相关的css,并不需要对业务逻辑做什么修改,就能拥有网页加载进度条,只要大家发挥想象力,那除了默认的进度条之外还能开发各种加载进度效果,使用起来非常方便。
那问题来了:pace.js是如何做到“自动”监控加载进度的呢?
pace.js监控了什么:
pace.js对于加载进度监控了什么呢?通过阅读源码,我们看到整体的进度有四个部分组成:document,elements,eventLag和ajax这四种监视器(Monitor)。
那接下来就来看看它们分别是什么。
首先是document。document就是我们所熟悉的HTMLDocument节点。document节点有一个事件,onreadystatechange,当document的readyState状态变化时会触发。因为无法准确的知道document到底加载了多少百分比,所以就用这个状态来做一个估算。在pace.js中将document的readyState的三个状态loadong,interactive和complete分别定义为0%,50%和100%。通过监听document节点的readyState状态变更,形成了pace.js的DocumentMonitor。
接下来是elements。我们可以通过配置传入一个css选择器列表,默认的选择器列表仅包含“body”。pace.js会按照设置的时间间隔搜索所有的选择器,如果能获得则认为这一项满足,所以elements这一项的加载进度就是 满足的选择器/全部的选择器。通过查询页面中制定的元素,就是pace.js的ElementMonitor。
然后是eventLag。EventLagMonitor其实只是一个“假的”监视器。它就在那里安静匀速的更新进度,这一小小的措施却带来了不错的用户体验,让用户不会因为加载“卡住了”而慌张。
pace.js是如何监控ajax的:
最后是用来监控ajax进度的AjaxMonitor。这是最有趣的一部分。如何才能监控所有ajax请求,并且不需要开发者修改自己或第三方的业务逻辑呢?
如果了解原生js的话,应该了解这几个类:XMLHttpRequest,XDomainRequest,WebSocket。这三个类分别用来发送ajax请求,跨域的ajax请求,以及websocket。如果能监控所有这些请求的时间,包括progress,load,error等等,我们就可以更新我们的加载进度了。
既然我们知道了要监控的对象,那我们便可以“请君入瓮”了,而这个瓮,就是代理模式:我们可以把原生的类保存起来,再用我们自己写的埋藏了“间谍”的类覆盖原生的类,这样当其他代码建立这些类的实例的时候,我们的“间谍”便悄悄开始监听加载进度了。
让我们来看一下代码:
// 保存原生的XMLHttpRequest
_XMLHttpRequest = window.XMLHttpRequest;
// 覆盖XMLHttpRequest
window.XMLHttpRequest = function(flags) {
var req;
// 调用原生的XMLHttpRequest
req = new _XMLHttpRequest(flags);
// 埋入我们的“间谍”
monitorXHR(req);
return req;
};
monitorXHR = function(req) {
var _open;
// “间谍”又对open方法埋入了间谍
_open = req.open;
return req.open = function(type, url, async) {
if (shouldTrack(type)) {
_this.trigger('request', {
type: type,
url: url,
request: req
});
}
return _open.apply(req, arguments);
};
};
通过代理模式埋了这些“间谍”后,我们就能对发起的ajax请求等做到监控,以更新加载进度。
当然pace.js也不是什么都监听了
除了以上这些,当然也有pace.js并没有监听的加载事件,比如script标签的加载。如果我们使用了sea.js或者require.js等,当js代码动态加载时并不会影响进度条,因为这里我们用动态建立script标签的方式加载js代码,而pace.js并没有对这方面进行监听。我们可以同样的代理appendChild方法,如果发现script标签被加到页面上,那么就监听它的加载进度。不过实际情况当然复杂的多,还有insertBefore,甚至innerHTML等方法都可以创建script标签加入文档并开始js的加载(当然一般就是appendChild和insertBefore啦)。
相似的还有css的加载,还要注意处理css的加载事件,在一些老的浏览器上,css并没有加载事件,还有加个定时不断检查css节点的cssRules和name来确定加载状况。
小结:
通过阅读pace.js的源码我们了解了pace.js的原理,同时学习了鸡贼的代理模式。比如在jasmine.js中也有个spy,可以监控制定函数被调用了几次,被什么参数调用了等等。灵活应用这种代理模式,可以方便我们扩展功能、进行调试等等。
pace.js原理简介的更多相关文章
- pace.js 原理(转)
pace.js监控了什么: pace.js对于加载进度监控了什么呢?通过阅读源码,我们看到整体的进度有四个部分组成:document,elements,eventLag和ajax这四种监视器(Moni ...
- Node.js 原理简介
Node.js 的官方文档中有一段对 Node.js 的简介,如下. Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript ...
- pace.js简介
Pace.js – 超赞的页面加载进度自动指示和 Ajax 导航效果 在页面中引入 Pace.js 和您所选择主题的 CSS 文件,就可以让你的页面拥有漂亮的加载进度和 Ajax 导航效果.不需要挂接 ...
- pace.js[转载]
pace.js监控了什么: pace.js对于加载进度监控了什么呢?通过阅读源码,我们看到整体的进度有四个部分组成:document,elements,eventLag和ajax这四种监视器(Moni ...
- storm 原理简介及单机版安装指南——详细版【转】
storm 原理简介及单机版安装指南 本文翻译自: https://github.com/nathanmarz/storm/wiki/Tutorial 原文链接自:http://www.open-op ...
- Pace.js – 超赞的页面加载进度自动指示和 Ajax 导航效果
在页面中引入 Pace.js 和您所选择主题的 CSS 文件,就可以让你的页面拥有漂亮的加载进度和 Ajax 导航效果.不需要挂接到任何代码,自动检测进展.您可以选择颜色和多种效果,有简约,闪光灯, ...
- pace.js和NProgress.js两个加载进度插件的一点小总结
这两个插件都是关于加载进度动画的,应该说各有特点吧,最起码对我来说是各有优势的.今天一天就捣鼓了加载进度动画,也研究了大量的(也就这两个)加载进度动画,也算对加载进度动画有了一个初步的了解了吧. NP ...
- pace.js – 加载进度条插件
这儿只是简单介绍一下这个插件pace.js. 在页面中引入Pace.js,页面就会自动监测你的请求(包括Ajax请求),在事件循环滞后,会在页面记录加载的状态以及进度情况.此插件的兼容性很好,可以兼容 ...
- Node.js的简介和安装
一.Node.js的简介和安装 a) 什么是Node.js? Node.js是一个开发平台 让JavaScript运行在服务器端的开发平台 ---简单点说就是用JavaScript写服务器 ...
随机推荐
- C#编写Windows服务程序图文教程
安装服务程序C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe 要安装的服务程序路径(如F:\***.exe)卸载服务程序C: ...
- MyEclipse报错 Building workspace has encountered a problem Errors occurred during the build 的2种解决方法
1: Building workspace has encountered a problem Errors occurred during the build 如果报错这个 那么有可能是jar包,报 ...
- CentOS6.5 安装snort
本机CentOS6.5最大化安装,以下安装所需组件也是最大化安装之后仍需自己安装的. 1.安装libpcap与libpcap-devel yum -y install libpcap* 2.安装lib ...
- npm install含义 及vue安装启动项目时报错解决及vue建项目时各文件间的依赖关系
全局安装vue-cli,使用命令npm install -g vue-cli. 下载模板代码,使用命令vue init webpack my-project,之后会有一些询问,按需填写即可. 最后会看 ...
- ural1553 Caves and Tunnels
Caves and Tunnels Time limit: 3.0 secondMemory limit: 64 MB After landing on Mars surface, scientist ...
- ZjDroid工具介绍及脱壳详细示例
前提条件: 1.Root手机一部 2.需要通过Xposed installer(http://dl.xposed.info/latest.apk)安装Xposed Framework; 一.ZjDro ...
- 第四弹:overfeat
overfeat是在AlexNet出现后,推出来的模型,其不仅用于物体分类,来用于定位,检测等,可以说是一个涉及很多应用场景的通用模型,值得看看. 本文将从两个方面来讲解,第一部分从论文角度来说一说, ...
- 常用HQL集锦
1.根据ID查询某"一个"实体类 方法1: String hql = "From ClassEntity as c where c.id=?"; ClassEn ...
- php中serialize、unserialize与json_encode、json_decode比较
性能比较 同一个变量编码或解码10000次,每个函数执行10000次所需时间 php5.2.13 json : 190 serialize : 257 json_encode : 0.08364200 ...
- mysql 插入数据后返回当前的自增ID方法
存储过程的写法: mysql>create procedure test( ->in username varchar(50), ->in password varchar(50), ...