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

如何让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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 05:03:27