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

求助:使用setInterval实现div宽度往复变化的原生JS方案

解决方案

一、使用setInterval的实现方案

先解决你之前的问题核心:错误通常源于步长计算偏差、状态切换逻辑疏漏,或是意外触发clearInterval。以下是精准实现的代码:

const line = document.querySelector('.line');
let currentWidth = 0;
let isExpanding = true;
const frameGap = 16; // 对应约60帧/秒的间隔
const singlePhaseDuration = 3000; // 单方向动画时长3秒
const step = 100 / (singlePhaseDuration / frameGap); // 每帧宽度变化量

const animationTimer = setInterval(() => {
  if (isExpanding) {
    currentWidth += step;
    // 到达100%时修正值并切换收缩状态
    if (currentWidth >= 100) {
      currentWidth = 100;
      isExpanding = false;
    }
  } else {
    currentWidth -= step;
    // 到达0时修正值并切换展开状态
    if (currentWidth <= 0) {
      currentWidth = 0;
      isExpanding = true;
    }
  }
  line.style.width = `${currentWidth}%`;
}, frameGap);

// 停止动画时调用:clearInterval(animationTimer)

关键说明

  • 用isExpanding状态变量精准切换展开/收缩阶段
  • 基于帧率计算每帧步长,避免动画跳变或提前终止
  • 到达边界值时强制修正宽度,防止后续计算出现异常

二、更优方案:使用requestAnimationFrame

虽然你指定用setInterval,但requestAnimationFrame是浏览器专为动画设计的API,性能更优、动画更流畅,且不会出现定时器时间偏移问题,推荐优先使用:

const line = document.querySelector('.line');
let startTime = null;
const fullCycleDuration = 6000; // 一个完整循环(展开+收缩)时长6秒

function animate(timestamp) {
  if (!startTime) startTime = timestamp;
  const elapsedTime = timestamp - startTime;
  // 计算当前循环进度:0-1对应一次完整的展开+收缩
  const progress = (elapsedTime % fullCycleDuration) / fullCycleDuration;
  
  let currentWidth;
  if (progress <= 0.5) {
    // 前3秒:从0到100%
    currentWidth = progress * 2 * 100;
  } else {
    // 后3秒:从100%到0
    currentWidth = (1 - (progress - 0.5) * 2) * 100;
  }
  
  line.style.width = `${currentWidth}%`;
  requestAnimationFrame(animate);
}

// 启动动画
requestAnimationFrame(animate);

// 停止动画时调用(需保存请求ID):
// const animationId = requestAnimationFrame(animate);
// cancelAnimationFrame(animationId);

关键说明

  • 基于时间戳计算进度,动画精度不受主线程阻塞影响
  • 通过取模运算天然实现无限循环,无需额外状态变量
  • 逻辑更简洁,避免定时器可能出现的累积误差

常见问题排查

你之前遇到的提前清除setInterval或功能失效,大概率是以下原因:

  • 定时器间隔设置不合理,导致步长计算错误,提前触发边界条件
  • 状态切换时未修正当前宽度值,导致下一阶段计算逻辑异常
  • 代码作用域问题导致定时器变量被意外覆盖,触发clearInterval

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 10:33:29