如何检测网页的加载进度。从而编写进度条

对于如何检测网页加载进度这个问题,百度了一下,没有好的答案。可以说是没有答案。但是找到了一个开源项目。
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;

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值