太阳集团城8722(中国·Macau)有限公司-Official website

 
   
0%
 
XML 地图

然后,我们对比 当前的时间 ,看是否超时:(为了方便复用代码,我把完成的部分封装成函数complete)

var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0var timer = 0var now = new Date()  // 记录当前时间
var timeout = 5000  // 超时时间

progress([80, 90], [1, 3], 100)

window.onload = () => {
  complete()
}if (now - loadingStartTime > timeout) {  // 超时
  complete()
} else {
  window.setTimeout(() => {  // 未超时,则等待剩余时间
    complete()
  }, timeout - (now - loadingStartTime))
}

function complete () {  // 封装完成进度功能
  progress(100, [1, 5], 10, () => {
    window.setTimeout(() => {
      $loading.hide()
    }, 1000)
  })
}

function progress (dist, speed, delay, callback) {
  var _dist = random(dist)
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {    if (prg + _speed >= _dist) {
      window.clearTimeout(timer)
      prg = _dist
      callback && callback()
    } else {
      prg += _speed
      progress (_dist, speed, delay, callback)
    }

    $progress.html(parseInt(prg) + '%')
    console.log(prg)
  }, _delay)
}

function random (n) {  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]    return Math.random() * times + offset
  } else {    return n
  }
}

至此,我们算是完整地实现了这一功能。

然而,事情还没有结束,少年你太天真。

如果目的是为了写一个纯粹障眼法的伪loading,那跟其他loading的实现就没什么区别了,我们做事讲究脚踏实地,能实现的实现,不能实现的,为了团队和谐,我们不得已坑蒙拐骗。那么我们还能更贴近实际情况一点吗?其实是可以的。

05具体场景分析

我们来分析一个场景,假设我们想让我们的loading更加真实一些,那么我们可以选择性地对页面上几个比较大的资源的加载进行跟踪,然后拆分整个进度条,比如我们页面有三张大图a、b、c,那么我们将进度条拆成五段,每加载完一张图我们就推进一个进度:

随机初始化[10, 20] ->

图a推进20%的进度 ->

图b推进25%的进度 ->

图c推进30%的进度 ->

完成100%

这三张图要占20% + 25% + 30% = 75%的进度。

问题是,如果图片加载完成是按照顺序来的,那我们可以很简单地:10(假设初始进度是10%) -> 30 -> 55 -> 85 -> 100,但事实是,图片不会按照顺序来,谁早到谁晚到是说不准的,所以我们需要更合理的方式去管理这些进度增量,使它们不会互相覆盖。

  1. 我们需要一个能够替我们累计增量的变量next;

  2. 由于我们的progress都是传目的进度的,我们需要另外一个函数add,来传增量进度。

var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0var timer = 0var now = new Date()
var timeout = 5000var next = prg

add([30, 50], [1, 3], 100)  // 第一阶段

window.setTimeout(() => {  // 模拟图a加载完
  add(20, [1, 3], 200)
}, 1000)

window.setTimeout(() => {  // 模拟图c加载完
  add(30, [1, 3], 200)
}, 2000)

window.setTimeout(() => {  // 模拟图b加载完
  add(25, [1, 3], 200)
}, 2500)

window.onload = () => {
  complete()
}if (now - loadingStartTime > timeout) {
  complete()
} else {
  window.setTimeout(() => {
    complete()
  }, timeout - (now - loadingStartTime))
}

function complete () {
  add(100, [1, 5], 10, () => {
    window.setTimeout(() => {
      $loading.hide()
    }, 1000)
  })
}

function add (dist, speed, delay, callback) {
  var _dist = random(dist)  if (next + _dist > 100) {  // 对超出部分裁剪对齐
    next = 100
  } else {
    next += _dist
  }

  progress(next, speed, delay, callback)
}

function progress (dist, speed, delay, callback) {
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {    if (prg + _speed >= dist) {
      window.clearTimeout(timer)
      prg = dist
      callback && callback()
    } else {
      prg += _speed
      progress (dist, speed, delay, callback)
    }

    $progress.html(parseInt(prg) + '%')
    console.log(prg)
  }, _delay)
}

function random (n) {  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]    return Math.random() * times + offset
  } else {    return n
  }
}

我们这里为了方便,用setTimeout来模拟图片的加载,真实应用应该是使用image.onload。

06结束

以上,就是我们一步步实现一个进度loading的过程了,演示代码可以戳我的codePen 写一个网页进度loading(http://codepen.io/Jack-Lo/pen/woZyRB)。

看似很简单的一个功能,其实仔细推敲,还是有很多细节要考虑的。

到这里,其实真的已经完成了,代码有点多有点乱是不是?你可以整理一下,封装成为插件的。

然而,好吧,其实我已经把这个进度封装成插件了。。。

没错,其实我就是来帮自己打广告的。。。

好吧,github仓库在此 ez-progress(https://github.com/jack-Lo/ez-progress)。

ez-progress 是一个web(伪)进度插件,使用 ez-progress 实现这个功能非常简单:

var Progress = require('ez-progress')
var prg = new Progress()

var $loading = $('#loading')
var $progress = $('#progress')

prg.on('progress', function (res) {
  var progress = parseInt(res.progress)  // 注意进度取整,不然有可能会出现小数
  $progress.html(progress + '%')
})

prg.go([60, 70], function (res) {
  prg.complete(null, [0, 5], [0, 50])  // 飞一般地冲向终点
}, [0, 3], [0, 200])

window.onload = function () {
  prg.complete(null, [0, 5], [0, 50])  // 飞一般地冲向终点
}

木油错,94这么简单!

原文来自:简书jack_lo

声明:所有来源为“澳门太阳集团城网址8722”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com

API百科
生活服务 企业工商 金融科技 接口大全 电子商务
API资讯
0512-88869195
数 据 驱 动 未 来
Data Drives The Future
XML 地图