AJAX请求加载时文本动画无法重复的问题求助
问题:AJAX加载期间文本动画无法重复播放
我想在AJAX请求加载时让文本执行弹跳动画,并且在请求未完成时重复这个动画,但现在动画跑完一次就停了,试了setTimeout和无限循环都没用,求帮忙分析原因并解决。
问题根源
- 动画未触发重绘:第一次给
.char设置animationName: bounce后,后续再设置相同值,浏览器认为属性没有变化,不会重新启动动画。 - delay变量持续累加:每次调用
repeatAnimation时,delay没有重置,会一直变大,导致后续的字符动画延迟越来越久,完全偏离预期节奏。 - 未终止动画循环:AJAX请求完成后,没有清理
setTimeout定时器,动画会一直后台运行,造成不必要的性能损耗。
修复方案
- 重新触发动画:每次循环时,先把
animationName设为none,再设回bounce,强制浏览器重绘启动动画;用requestAnimationFrame确保浏览器完成重绘后再设置动画,避免无效操作。 - 重置delay变量:每次调用
repeatAnimation时,把delay重置为0,保证每次循环的字符动画都从初始延迟开始,维持统一节奏。 - 添加定时器清理:用变量存储定时器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
相关产品推荐
相关产品推荐

