H5 progress js结合实现动态进度条显示小记

开通csdn好久了,出于工作原因,一直不能在网上记录,但是终究觉得还是得留下些东西,所以开始整理笔记,调出可以记录的描述一下,目的也是为了看到自己的成长,与大家共享。

今天这个是最近刚用过的,一直听说H5的进度条标签,一直也没用过,这两天刚好提出了需求,走起,小试一把,然后就记录一下吧,其实还是蛮简单的,重点就是建立好轮询。

出于一些原因,有些地方我会用伪代码来标识。

第一步:就是在页面里写好你想要进度展示的标签,如果完全已知各种显示样式和情况,建议就直接写在html里,js控制显隐就行,这样比js插入dom要省些开销。

<div id="loading" class="loading">
     <div id="pre">
         正在检测:<progress id="progressPre" />
      </div>
      <div id="ready" class="hidden">
            开始下载:
           <progress id="progress" value="0" max="100" />
      </div>
      <div id="noWay" class="hidden">
                无法下载!
      </div>
</div>

第二步:在js里利用ajax建立好轮询机制,当然,可以用Comet和SSE,原理差不多,完全根据自己和实际的资源支持情况来定,我这边就只能用ajax了。

因为要分别测试是否可下载,然后反馈下载进度或者无法下载,所以建立了两次轮询,一次负责轮询是否可下载,一次负责进行下载进度反馈,这里先把原理阐述,然后再贴代码。

第一次轮询:将会像后台询问是否可下载,由于该步骤是通过查询数据库数据来实现,所以,一定一定不要轮询太频繁,否则频繁连接数据库,后果可能很严重(当然如果服务器和数据库很牛逼的,可以选择性忽略,但是依然应该本着节约资源的原则开发,嗯是的),我这里设定了3000ms轮询一次,根据服务器的反馈,这个频率基本足够,最多也就是2次就可以得到结果了。然而,这里依然有个坑,就是用于轮询反馈的字段值,还是不要用0来标识了,因为貌似mysql在没有值的时候(null),查询返回前台页面的也是个0,我就被坑了,所有不管怎么样,尽量不要用0来标识。注意以上两点,这部分就很简单了, 写好ajax,放入setInterval或者setTimeout链就可以了,在ajax的成功函数里,根据返回值停止调用或者继续调用。

第二次轮询:如果可以下载,则进入第二次轮询,查询文件下载进度;否则就没有这一步了,直接反馈不可下载结束。这里就说一下进度条<progress>了,有两个属性value和max,前者是当前完成的数值,后者是最大数值。所以不管你想进度什么东西,都要确定这两个数据,而且一定要匹配;如果是时间,就都用时间,如果是字节,就都用字节,否则会与实际情况不匹配。另外,如果你无法确定可以拿到这两个数据,或者有一个无法拿到,那么可能,就不能用了(这里只是我针对这个标签的结论,也许有大神会有其他方法)。一切如果无误,则继续ajax,建立轮询,我这里是下载文件, 所有这次就只需要根据保存文件地址,不断去轮询查看文件大小,就知道当前文件下载了多少,返回这个值,赋给value属性,就可以在前台看到进度条变化了。

伪代码如下:

第一次轮询
var timer = setInterval/setTimeout(function a() {
	ajax({
        url:url,
        data:data,
        success:function(data){
            if(dataright){
               clearInterval(timer); //如果是setTimeout链,不需要这个。
               doOtherTing get max value;
                set max value to attr max;
               start downloadTimer;
            }else{
                //如果用的是setTimeout链,这里继续调用setTimout,否则不用写else
                setTimout(a,3000)
            }
        }
    })
}, 3000)

第二次轮询
var downloadtimer = setInterval/setTimeout(function a() {
	ajax({
        url:url,
        data:data,
        success:function(data){
            if(data < max){
                set data to attr value
               setTimout(a,3000)  //如果用的是setTimeout链,这里继续调用setTimout
            }else{
                clearInterval(timer); //如果是setTimeout链,不需要这个else。
             }
        }
    })
}, 1000)

如此一来,动态进度条就完成了。

总结一下要点:

扫描二维码关注公众号,回复: 2972954 查看本文章

1 . 写好要显示的progess标签;

2.  根据实际需求建立轮询机制,特别注意0值的问题,以及最大值和当前值的获取问题;

3. 如果用定时器,建议setTimeout链,因为第一不需要手动清除,完事自己就停,第二,setInterval在js线程比较繁忙时,说白了,不能按既定时间来处理队列的定时任务,有可能会跳过队列中某一个已加入的任务;

4. 轮询的次数一定要注意,根据服务器和实际情况来确定,不可盲目频繁进行,要为服务器考虑哈;

5. 如果有大神有更好的方法,欢迎留言解惑,不胜感激

猜你喜欢

转载自blog.csdn.net/qq_38047742/article/details/81352146