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

AJAX请求加载时文本动画无法重复的问题求助

问题:AJAX加载期间文本动画无法重复播放

我想在AJAX请求加载时让文本执行弹跳动画,并且在请求未完成时重复这个动画,但现在动画跑完一次就停了,试了setTimeout和无限循环都没用,求帮忙分析原因并解决。

问题根源

  • 动画未触发重绘:第一次给.char设置animationName: bounce后,后续再设置相同值,浏览器认为属性没有变化,不会重新启动动画。
  • delay变量持续累加:每次调用repeatAnimation时,delay没有重置,会一直变大,导致后续的字符动画延迟越来越久,完全偏离预期节奏。
  • 未终止动画循环:AJAX请求完成后,没有清理setTimeout定时器,动画会一直后台运行,造成不必要的性能损耗。

修复方案

  1. 重新触发动画:每次循环时,先把animationName设为none,再设回bounce,强制浏览器重绘启动动画;用requestAnimationFrame确保浏览器完成重绘后再设置动画,避免无效操作。
  2. 重置delay变量:每次调用repeatAnimation时,把delay重置为0,保证每次循环的字符动画都从初始延迟开始,维持统一节奏。
  3. 添加定时器清理:用变量存储定时器ID,AJAX完成后调用clearTimeout终止动画循环,避免资源浪费。

修改后的JavaScript代码

document.getElementById("generateButton").addEventListener("click", function() {
  var loadingIndicator = document.getElementById("loadingIndicator");
  loadingIndicator.style.display = "block";

  var chars = document.querySelectorAll(".char");
  var animationTimer; // 存储定时器ID,用于后续清理

  function repeatAnimation() {
    let delay = 0; // 每次循环重置delay为0
    chars.forEach(function(char) {
      setTimeout(function() {
        // 先清除动画,再重新设置,触发重绘
        char.style.animationName = "none";
        // 确保浏览器完成重绘后再启动动画
        requestAnimationFrame(() => {
          char.style.animationName = "bounce";
        });
      }, delay);
      delay += 100;
    });

    // 延迟时间设为所有字符动画完成时间+1秒,避免前后循环重叠
    animationTimer = setTimeout(repeatAnimation, chars.length * 100 + 1000); 
  }

  var descriptionValue = document.getElementById("description").value;
  var titleValue = document.getElementById("title").value;

  var xhr = new XMLHttpRequest();
  xhr.open("POST", "/generationDescription", true);
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      loadingIndicator.style.display = "none";
      clearTimeout(animationTimer); // AJAX完成后停止动画循环

      if (xhr.status === 200) {
        var response = JSON.parse(xhr.responseText);
        document.getElementById("description").value = response.description;
        document.getElementById("shortDescription").value =
          response.shortDescription;
      }
    }
  };

  var data =
    "description=" +
    encodeURIComponent(descriptionValue) +
    "&title=" +
    encodeURIComponent(titleValue);
  repeatAnimation();
  xhr.send(data);
});

CSS代码(保留原样式)

@keyframes bounce {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-10px);
  }
}

.loading-indicator .char {
  display: inline-block;
  animation-duration: 1s;
  animation-fill-mode: both;
  animation-name: none;
}

HTML代码(保留原结构)

<div id="loadingIndicator" class="loading-indicator" style="display: none;">
  <span class="char">C</span>
  <span class="char">h</span>
  <span class="char">a</span>
  <span class="char">r</span>
  <span class="char">g</span>
  <span class="char">e</span>
  <span class="char">m</span>
  <span class="char">e</span>
  <span class="char">n</span>
  <span class="char">t</span>
  <span class="char"> </span>
  <!-- 单词间空格 -->
  <span class="char">e</span>
  <span class="char">n</span>
  <span class="char"> </span>
  <!-- 单词间空格 -->
  <span class="char">c</span>
  <span class="char">o</span>
  <span class="char">u</span>
  <span class="char">r</span>
  <span class="char">s</span>
  <span class="char">.</span>
  <span class="char">.</span>
  <span class="char">.</span>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:58:11