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

如何解决浏览器标签页失焦时自定义进度条停止运行的问题

问题根因

你遇到的暂停现象是浏览器的默认性能优化策略:当标签页处于后台失焦状态时,setInterval、requestAnimationFrame 等定时器回调会被大幅降频甚至暂停执行,直到标签页重新被激活才会恢复执行,所以你原来逐帧累加宽度的逻辑就会卡住。

可行实现方案

不要逐帧累加进度值,改为记录进度条启动的起始时间,每次更新时用当前时间和起始时间的差值占总预期时长的比例,计算出当前应有的进度值。就算中间定时器被暂停,重新触发时会直接按真实流逝的时间算出正确的进度,不会出现累计延迟的问题,这也是绝大多数站点进度条的通用实现逻辑。

改后可用的完整代码如下:

<div class="slide-progress-bar">
  <div class="progress-bar" id="progress-bar"></div>
  <!--progress-bar-->
</div>
<script>
var elem = document.getElementById("progress-bar");
// 进度条总时长,单位毫秒,对应原逻辑的30秒总加载时长
const TOTAL_DURATION = 30000;
let startTime = null;
let timerId = null;

function progressBar() {
  resetProgressBar();
  // 记录进度启动的时间戳
  startTime = Date.now();
  timerId = setInterval(frame, 300);

  function frame() {
    // 按真实流逝时间计算进度
    const elapsed = Date.now() - startTime;
    const width = Math.min(100, elapsed / TOTAL_DURATION * 100);
    elem.style.width = width + "%";
    // 进度满后清除定时器
    if (width >= 100) {
      clearInterval(timerId);
    }
  }
}
function resetProgressBar() {
  if (timerId) clearInterval(timerId);
  elem.style.width = "1%";
}
progressBar()
</script>
<style>
.slide-progress-bar {
  background-color:rgba(155, 155, 155, 0.36);
  display: inline-block;
  vertical-align: middle;
  margin: auto;
  width: 100%;
}

.progress-bar {
  height: 5px;
  background-color: #ff4546;
  position: relative;
  transition: width 0.3s linear;
}
</style>

这个方案的优势:

  • 就算标签页在后台时定时器被暂停,切回后第一次执行回调就会直接计算出当前真实的进度,进度条会直接跳到对应位置,不会出现暂停后累计落后的问题
  • 不需要引入额外复杂API,兼容性覆盖所有主流浏览器
  • 如果需要更平滑的动画效果,也可以把setInterval换成requestAnimationFrame,配合这套时间差计算逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:06:04