You need to enable JavaScript to run this app. 如何实现提交触发的虚拟进度条,数据返回渲染后自动完成消失
优惠活动
大模型
产品
解决方案
定价
更多

如何实现提交触发的虚拟进度条,数据返回渲染后自动完成消失

虚拟进度条实现方案

1. 修正原有进度条模板的问题

你原有模板存在重复写style、样式不可见、默认展示的问题,先调整为默认隐藏、进度条填充色可见的版本:

<!-- 默认隐藏,提交后再显示 -->
<div id="loadingcontainer" style="display: none; position: fixed; top: 0; left: 0; width: 100%; z-index: 9999;">
  <div class="progress" style="height: 5px; margin: 0; background-color: #f0f0f0;">
    <div id="myprogress" class="progress-bar" role="progressbar" style="color:#EB7051; background-color: #EB7051; width: 0%; transition: width 0.2s ease;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
  </div>
</div>
  • 给进度条容器加了固定定位、高z-index,保证进度条始终在页面最顶部不被遮挡
  • 合并了重复的style属性,修正了原来白色进度条不可见的问题,填充色使用你指定的#EB7051
  • 初始宽度设为0,容器默认隐藏,符合提交后才展示的逻辑
  • 加了宽度过渡动画,进度变化更顺滑

2. 虚拟进度条核心逻辑实现

虚拟进度条的核心逻辑是「加载中慢爬、完成时直接拉满」,避免真实请求未返回时进度提前走完的违和感:

  • 用全局变量存储定时器,防止多次提交生成多个定时器导致进度异常加快
  • 启动函数:触发时显示进度条,每100ms增加少量宽度,最多爬到80%就停住,越接近80%涨速越慢,更符合真实加载体感
  • 完成函数:接口返回、页面渲染准备完成时,清除定时器,直接把进度拉到100%,停留300ms后隐藏进度条并重置宽度,给用户明确的加载完成感知

核心功能代码:

let progressTimer = null;
// 启动进度条
function startProgress() {
  const progressBar = document.getElementById('myprogress');
  const container = document.getElementById('loadingcontainer');
  // 先重置状态,避免上次加载的残留
  container.style.display = 'block';
  progressBar.style.width = '0%';
  progressBar.setAttribute('aria-valuenow', 0);

  // 启动定时器爬进度,最多到80%就停
  progressTimer = setInterval(() => {
    let currentWidth = parseFloat(progressBar.style.width);
    if (currentWidth < 80) {
      // 分段设置涨速:前期快、后期慢,模拟真实加载体感
      const increment = currentWidth < 30 ? 5 : currentWidth < 60 ? 3 : 1;
      currentWidth = Math.min(currentWidth + increment, 80);
      progressBar.style.width = `${currentWidth}%`;
      progressBar.setAttribute('aria-valuenow', currentWidth);
    }
  }, 100);
}

// 完成进度条
function finishProgress(callback) {
  clearInterval(progressTimer);
  const progressBar = document.getElementById('myprogress');
  const container = document.getElementById('loadingcontainer');
  // 直接拉到100%
  progressBar.style.width = '100%';
  progressBar.setAttribute('aria-valuenow', 100);
  // 停留300ms让用户感知到加载完成
  setTimeout(() => {
    container.style.display = 'none';
    // 执行后续的渲染回调
    callback && callback();
  }, 300);
}

3. 改造原有提交逻辑适配进度条

  • 关键时序注意点:当前代码用document.open()+document.write()重写整个页面,旧页面的DOM(包括进度条)会被直接替换,因此必须等进度条拉到100%、短暂展示后,再执行文档渲染逻辑,避免进度条提前消失。

同时把原有的嵌套异步回调改成async/await形式,保证请求流程可控,异常场景也能正确清理进度条状态:

function searchIt() {
  let form = document.querySelector('form')
  form.addEventListener('submit', async(e) => {
    e.preventDefault()
    // 提交先启动进度条
    startProgress();
    let urlIN = form.url.value
    let url = encodeURIComponent(urlIN)
    try {
      // 等待接口返回
      const res = await fetch('/', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ url })
      })
      // 拿到响应文本先存下来,不直接写页面
      const htmlText = await res.text();
      // 进度条走完,再执行页面重写渲染
      finishProgress(() => {
        document.open()
        document.write(htmlText)
        document.close() // 补充close方法,避免文档流异常
      })
    } catch (err) {
      console.error(err)
      // 请求失败也要清理进度条,避免一直卡在加载状态
      clearInterval(progressTimer)
      document.getElementById('loadingcontainer').style.display = 'none'
      alert('请求失败,请稍后重试')
    }
  })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.06 14:06:10