如何检测网页的加载进度。从而编写进度条
来源:互联网 发布:淘宝智能版全屏店招 编辑:程序博客网 时间:2024/05/16 04:33
对于如何检测网页加载进度这个问题,百度了一下,没有好的答案。可以说是没有答案。但是找到了一个开源项目。
pace.js
如何想直接用现成的进度条。这个库很丰富,现在想要分析一下它的源代码来了解,如何检测网页加载进度,方便我们编写自己的js组件 。
pace.js 代码不多 。才1千行。
start: When pace is initially started, or as a part of a restart
stop: When pace is manually stopped, or as a part of a restart
restart: When pace is restarted (manually, or by a new AJAX request)
done: When pace is finished
hide: When the pace is hidden (can be later than done, based on ghostTime and minTime)
上面是它的进度条的生命周期。
经过分析,它的核心方法在go这个函数里。
Pace.go = function() { var start; Pace.running = true; bar.render(); start = now(); cancelAnimation = false; return animation = runAnimation(function(frameTime, enqueueNextFrame) { var avg, count, done, element, elements, i, j, remaining, scaler, scalerList, sum, _j, _k, _len1, _len2, _ref2; remaining = 100 - bar.progress; count = sum = 0; done = true; for (i = _j = 0, _len1 = sources.length; _j < _len1; i = ++_j) { source = sources[i]; scalerList = scalers[i] != null ? scalers[i] : scalers[i] = []; elements = (_ref2 = source.elements) != null ? _ref2 : [source]; for (j = _k = 0, _len2 = elements.length; _k < _len2; j = ++_k) { element = elements[j]; scaler = scalerList[j] != null ? scalerList[j] : scalerList[j] = new Scaler(element); done &= scaler.done; if (scaler.done) { continue; } count++; sum += scaler.tick(frameTime); } } avg = sum / count; bar.update(uniScaler.tick(frameTime, avg)); if (bar.done() || done || cancelAnimation) { bar.update(100); Pace.trigger('done'); return setTimeout(function() { bar.finish(); Pace.running = false; return Pace.trigger('hide'); }, Math.max(options.ghostTime, Math.max(options.minTime - (now() - start), 0))); } else { return enqueueNextFrame(); } }); };
因为在这个函数我们看到了,以下几个 关键方法的调用
bar.render(); remaining = 100 - bar.progress; bar.update(100); Pace.trigger('done'); bar.finish(); Pace.running = false; return Pace.trigger('hide');
表现了进度条从生成到隐藏。
那么推导出来关键的变量在于bar.progress的变化原因
找到了
for (i = _j = 0, _len1 = sources.length; _j < _len1; i = ++_j) { source = sources[i]; scalerList = scalers[i] != null ? scalers[i] : scalers[i] = []; elements = (_ref2 = source.elements) != null ? _ref2 : [source]; for (j = _k = 0, _len2 = elements.length; _k < _len2; j = ++_k) { element = elements[j]; scaler = scalerList[j] != null ? scalerList[j] : scalerList[j] = new Scaler(element); done &= scaler.done; if (scaler.done) { continue; } count++; sum += scaler.tick(frameTime); } }
看SOURCE_KEYS
SOURCE_KEYS = {
ajax: AjaxMonitor,
elements: ElementMonitor,
document: DocumentMonitor,
eventLag: EventLagMonitor
};
这是一个页面的组成部分。
上面的那个两层循环就是在循环它们的每个元素是否加载完成 。
他们每个监视器都有一个tracker
function EventLagMonitor() { var avg, interval, last, points, samples, _this = this; this.progress = 0; avg = 0; samples = []; points = 0; last = now(); interval = setInterval(function() { var diff; ... if (++points >= options.eventLag.minSamples && avg < options.eventLag.lagThreshold) { _this.progress = 100; return clearInterval(interval); } else { return _this.progress = 100 * (3 / (avg + 3)); } }, 50); }
XHRRequestTracker = (function() { function XHRRequestTracker(request) { var event, size, _j, _len1, _onreadystatechange, _ref2, _this = this; this.progress = 0; if (window.ProgressEvent != null) { size = null; request.addEventListener('progress', function(evt) { if (evt.lengthComputable) { return _this.progress = 100 * evt.loaded / evt.total; } else { return _this.progress = _this.progress + (100 - _this.progress) / 2; } }, false); _ref2 = ['load', 'abort', 'timeout', 'error']; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { event = _ref2[_j]; request.addEventListener(event, function() { return _this.progress = 100; }, false); } } else {
SocketRequestTracker = (function() { function SocketRequestTracker(request) { var event, _j, _len1, _ref2, _this = this; this.progress = 0; _ref2 = ['error', 'open']; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { event = _ref2[_j]; request.addEventListener(event, function() { return _this.progress = 100; }, false); } } return SocketRequestTracker;
所以检测页面加载进度的思路如下
SOURCE_KEYS = {
ajax: AjaxMonitor,
elements: ElementMonitor,
document: DocumentMonitor,
eventLag: EventLagMonitor
};
获取以上类别的所有元素。为每个Monitor创建一个Tracker。然后为每个元素addeventListener(“progress”,function(){ 获取进度})。
然后遍历所有元素的进度。
如果加载完成就Continue然后去执行一下动画
否则就进度剩余的部分++;
在循环开始有一个done变量,与所有的元素的.done进行&=,如果最后结果是true,那么进度条就完成 ,可以hide了。
而这个检测进度的方法是不断调用自身的。直到done=true;
- 如何检测网页的加载进度。从而编写进度条
- 网页顶部加载进度条(真实加载进度)
- 请问如何禁止进度条拖放功能?只想进度条显示播放进度以及加载进度,但不能拖放进度,请问如何禁止播放器的拖放。
- 常用的网页加载进度条
- 常用的网页加载进度条
- 网页加载进度页面
- android中各式各样的进度条,加载进度,太棒了
- 使用ImageLoader加载网络图片时,如何获取加载进度,如何设置进度条
- 很完美的jquery网页加载进度条
- 变态的网页加载进度条实现思路
- WedView的加载网页与进度条
- 进度条的进度
- 常用的网页加载进度条之【制作进度条】
- 网页加载进度条
- Android 加载网页进度条
- 网页加载进度条。
- 网页顶部加载进度条
- 获取网页加载进度条
- 小南的数据结构目录
- mpi中ssh实现MPI节点间的无密码访问
- C++设计模式之中介者模式
- 百度2015春季实习生招聘附加题_01排序
- Spring_SpringMVC_MyBaties框架搭建是 jdbc.properties文件注意事项
- 如何检测网页的加载进度。从而编写进度条
- 栈回溯技术
- 基于Matlab中FDATool工具箱的滤波器设计及相关文件的生成
- 高效能人士的七个习惯(读书笔记)
- 安装VisualDSP++出现Install cannot proceed.Could not find XML file or the XML file may be corrupted!
- Android ART Runtime – dex2oat
- 文本编码区别
- Struts2上传单个或多个文件
- web.xml之filter使用详解