两种JS模拟进度条周期更新进度的方式

记录下两种进度条周期更新的实现方式,脱离具体场景,这里用随机数来表示每次的变化值。

H5进度条

在H5中实现一个进度条非常方便,直接用<progress>标签即可

<progress style="width: 20%; height: 30px"></progress>

在没有配置value属性的情况下,进度条属于等待阶段,会有自带的动画效果。例如下面就是Chrome中的效果,蓝色的一小段回来回摆动

1-progress.png

想要显示进度,需要设置valuemax属性,分别表示当前值和最大值,例如

<progress value=20 max=100 style="width: 20%; height: 30px"></progress>

这时候进度条会走到百分之20的地方

2-20.png

所以在实际使用中,只需要按比例计算出value值即可。

周期更新进度

模拟思路是每100毫秒给value增加一个0-5的随机值,从0开始一直增加到100,弹出成功的提示。

方法一,利用setInterval()来实现。

html如下

<progress value=0 max=100 style="width: 20%; height: 30px"></progress><br>
<button type="button">Start</button>

js如下

prog = document.getElementsByTagName('progress')[0];
btn=document.getElementsByTagName('button')[0];
function increase(){
    let timer = setInterval(function(){
        if(prog.value<100){
            prog.value=prog.value+Math.random()*5;
        }
        else{
            clearInterval(timer);
            alert("100% done!");
        }
    },100);
}
btn.onclick=increase;

这种方法比较好理解,点击按钮触发setInterval(),每100毫秒运行回调函数,如果value值小于100就增加,否则就提示成功,并且执行clearInterval()。因为要执行清除操作,前面的定时器要记得赋值给变量。

方法二,利用setTimeout()来实现

html和上面一样,js如下

function increase(){
    setTimeout(function(){
        if(prog.value<100){
            prog.value=prog.value+Math.random()*5;
            increase();
        }else{
            alert("100% done!");
        }
    },100);
}
btn.onclick=increase;

每次执行increase()函数都会在100毫秒后将一个回调函数放入任务队列,回调函数判断value的值,如果小于100就增加,并且再次调用increase()

注意,如果不理解js的异步操作原理,很容易写出下面的错误代码,导致浏览器进入死循环

btn.onclick=function(){
    while(prog.value < 100){
        setTimeout(function(){
            prog.value=prog.value+Math.random()*5;
            console.log(prog.value)
        },100);
    };
    alert("100% done!");
};

错误的根本原因是setTimeout()会在整个函数执行完之后才会被加入任务队列,所以只要这里的循环不退出,函数就不会结束,setTimeout()就永远都不会执行。更详细的JS异步操作原理,可以参考另外一篇博客《Javascript的异步原理和事件循环图文详解》

实际使用场景

这里是用随机数进行的模拟,实际使用中,需要自己去计算。

例如ajax请求场景中,就需要为xhr绑定progress事件,在回调函数中获取下载量和下载总量动态更新到进度条的value值中,这一块可以参考这里这里

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用 MFC 编写的多线程更新进度条的示例代码,其中使用 PostMessage 函数向主线程发送消息更新进度条的进度: 首先,在主线程中定义一个消息常量: ```cpp #define WM_UPDATE_PROGRESS_BAR (WM_USER + 1) ``` 然后,在主线程中创建一个进度条控件,并启动一个后台线程: ```cpp BOOL CMyDialog::OnInitDialog() { CDialogEx::OnInitDialog(); // 创建进度条控件 m_progressBar.Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH, CRect(10, 10, 200, 30), this, IDC_PROGRESS_BAR); // 启动后台线程 AfxBeginThread(UpdateProgressBarThreadProc, this); return TRUE; } ``` 在后台线程中,使用 Sleep 函数模拟一些计算任务,并通过 PostMessage 函数向主线程发送消息更新进度条的进度: ```cpp UINT CMyDialog::UpdateProgressBarThreadProc(LPVOID pParam) { CMyDialog* pThis = (CMyDialog*)pParam; for (int i = 0; i <= 100; i++) { // 模拟一些计算任务 Sleep(50); // 发送消息更新进度条的进度 pThis->PostMessage(WM_UPDATE_PROGRESS_BAR, i, 0); } return 0; } ``` 在主线程的消息映射函数中,处理更新进度条的消息: ```cpp BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx) ON_MESSAGE(WM_UPDATE_PROGRESS_BAR, OnUpdateProgressBar) END_MESSAGE_MAP() LRESULT CMyDialog::OnUpdateProgressBar(WPARAM wParam, LPARAM lParam) { int nProgress = (int)wParam; // 更新进度条的进度 m_progressBar.SetPos(nProgress); return 0; } ``` 这样,当后台线程发送消息更新进度条的进度时,主线程就会处理这个消息,并更新进度条的进度

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值