如何让JavaScript递归文本动画函数执行完成后再显示按钮?
解决逐字文本动画完成后再显示按钮的问题
一、给原函数添加回调函数
原代码的问题是没有对外通知动画结束的时机,给函数加个回调参数,在动画执行完时触发即可:
修改后的代码:
var showText = function (target, message, index, interval, callback) { if (index < message.length) { $(target).append(message[index++]); setTimeout(function () { showText(target, message, index, interval, callback); }, interval); } else { // 动画结束,执行传入的回调逻辑 if (typeof callback === 'function') { callback(); } } }
调用示例(假设按钮的id是start-btn):
showText('#text-container', '欢迎来到文字游戏!', 0, 150, function() { $('#start-btn').show(); });
二、用Promise封装(更符合现代JS写法)
Promise能更清晰地处理异步等待逻辑,适合新手理解“等动画做完再执行下一步”的流程:
封装后的函数:
function showText(target, message, interval = 100) { return new Promise((resolve) => { let index = 0; const $target = $(target); $target.empty(); // 先清空目标容器,避免重复追加文本 function type() { if (index < message.length) { $target.append(message[index++]); setTimeout(type, interval); } else { resolve(); // 动画完成,告知外部可以继续执行后续逻辑 } } type(); }); }
调用时可以用两种方式:
// 方式1:用then链式调用 showText('#text-container', '这是一段逐字显示的文本', 120).then(() => { $('#start-btn').show(); }); // 方式2:用async/await(需要在async函数内使用) async function initGame() { await showText('#text-container', '这是一段逐字显示的文本', 120); $('#start-btn').show(); } initGame();
三、更流畅的逐字动画优化方案
如果想让动画更流畅,避免浏览器节流导致的延迟,可以用requestAnimationFrame代替setTimeout,它会同步浏览器的刷新频率:
function showText(target, message, interval = 100) { return new Promise((resolve) => { let index = 0; const $target = $(target); $target.empty(); let lastRenderTime = 0; function type(timestamp) { if (!lastRenderTime) lastRenderTime = timestamp; // 达到设定间隔才渲染下一个字符 if (timestamp - lastRenderTime >= interval) { $target.append(message[index++]); lastRenderTime = timestamp; } if (index < message.length) { requestAnimationFrame(type); } else { resolve(); } } requestAnimationFrame(type); }); }
调用方式和Promise版本一致,同样可以等待动画结束后显示按钮。
内容的提问来源于stack exchange,提问作者matchafluff
相关产品推荐
相关产品推荐

