You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在网站计算任务执行期间显示加载动画并在完成后隐藏

问题场景

正在开发支持数值计算、图表绘制功能的网站,需要实现计算运行阶段展示加载动画、计算和绘图全部完成后动画自动消失的交互效果。

补充说明:该效果和页面初始加载流程无关,常规的页面初始化加载器方案不适用。

现有实现逻辑

  • 点击id为submitButton的触发按钮时,将承载加载动画、id为loader的div容器的display样式设置为flex,尝试显示加载动画
  • 后续待执行逻辑:生成指定长度的随机数组、执行permutationGeneration排列生成函数、统计计算耗时、完成最终图表绘制
  • 当前卡点:仅实现了加载动画的触发显示逻辑,无法在计算执行完毕、图表绘制结束后,将loader的display样式改回none以隐藏动画

现有代码片段如下:

document.getElementById("submitButton").onclick=function()
{

  document.getElementById("loader").style.display='flex';  // 加载动画容器

  const permutationGeneration = (arr = []) => {
    let res = []
    const helper = (arr2) => {
      if (arr2.length==arr.length)
      return res.push(arr2)
      for(let e of arr)
      if (!arr2.includes(e))
      helper([...arr2, e])
    };
    helper([])

    delete result;
    return;
  };
    
    var randArray=Array.from({length : size}, () => Math.floor(Math.random() * 100000));
   
    timeReq = new Date().getTime();
    permutationGeneration(randArray);
    timeReq = ((new Date().getTime()) - timeReq)/1000;

}
问题根因

浏览器JS运行在单线程事件循环模型下:如果在设置loader.style.display='flex'后直接执行同步的耗时计算逻辑,浏览器会被计算任务占满线程,没有空闲执行页面重渲染,用户根本看不到加载动画;就算在计算代码最后直接加隐藏逻辑,也会出现动画全程不显示、或者闪一下就消失的问题。

另外原代码的permutationGeneration函数存在逻辑错误:内部生成的排列结果res没有对外返回,末尾的delete result是无效代码,不会产生实际作用。

修复方案
  1. 用setTimeout(fn, 0)将计算、绘图逻辑包裹,推入下一个宏任务队列,给浏览器留出重渲染时间,确保加载动画能正常显示
  2. 在所有计算、绘图逻辑全部执行完成的位置,添加隐藏loader的代码
  3. 修正原排列生成函数的返回逻辑

修正后可直接运行的代码如下:

document.getElementById("submitButton").onclick = function() {
  const loaderEl = document.getElementById("loader");
  // 触发展示加载动画
  loaderEl.style.display = 'flex';

  const permutationGeneration = (arr = []) => {
    let res = []
    const helper = (arr2) => {
      if (arr2.length == arr.length) {
        res.push(arr2)
        return
      }
      for(let e of arr) {
        if (!arr2.includes(e)) {
          helper([...arr2, e])
        }
      }
    };
    helper([])
    // 移除无效的delete逻辑,返回生成的排列结果
    return res;
  };

  // 将耗时逻辑放入setTimeout,等浏览器渲染完加载动画后再执行
  setTimeout(() => {
    const randArray = Array.from({length : size}, () => Math.floor(Math.random() * 100000));
   
    const timeStart = new Date().getTime();
    const generateResult = permutationGeneration(randArray);
    const timeReq = ((new Date().getTime()) - timeStart)/1000;

    // 此处插入你的图表绘制逻辑
    // ...... 图表绘制代码 ......
    // 如果绘图逻辑是异步的(比如第三方图表库的渲染回调),需要把隐藏loader的代码放到对应的完成回调中

    // 全部逻辑执行完毕,隐藏加载动画
    loaderEl.style.display = 'none';
  }, 0)
}

注意事项

  • 如果使用的图表库存在异步渲染逻辑,不要直接在调用绘图接口后就隐藏loader,需要把隐藏逻辑放到图表库提供的rendered/finished类回调函数中,避免图表还没绘制完成动画就提前消失
  • 如果计算量特别大,更推荐将计算逻辑放到Web Worker中执行,避免阻塞主线程导致加载动画卡顿

内容的提问来源于stack exchange,提问作者Chandranshu Gautam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 07:48:20