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

文本淡入淡出切换的理想实现方式 解决文本未完全淡出就提前更新的问题

问题原因分析

现有实现存在三个核心问题导致文本提前更新:

  1. setTimeout计时不准确:JavaScript的宏任务计时器受主线程任务排队、浏览器定时器精度调整影响,回调实际执行时间和设定的125ms经常出现偏差,无法和淡出动画的完成时间完全匹配。
  2. 无动画防重入机制:短时间多次调用showInfo函数时会生成多个定时器队列,前一次的定时器回调可能在后一次触发的淡出过程中执行,直接更新文本。
  3. 样式设置逻辑缺陷:fadeOut中同步设置visibility: hidden,而visibility属于离散过渡属性,不会跟随opacity渐变生效,可能导致元素状态切换和透明度过渡不同步。
优化实现方案
// 新增动画状态锁,避免重复触发动画
let isAnimating = false

function showInfo(text = '') {
    // 动画进行中直接拒绝新请求,避免逻辑冲突
    if (isAnimating) return
    isAnimating = true
    freeze_input = true

    // 绑定单次transitionend事件,淡出真实完成后再执行后续逻辑
    const onFadeOutEnd = () => {
        // 及时解绑事件避免重复触发和内存泄漏
        question_text.removeEventListener('transitionend', onFadeOutEnd)
        question_text.style.transition = 'none'
        
        question_text.style.display = ''
        if (text !== '') {
            question_text.innerText = text
        }
        // 强制浏览器重绘,确保内容更新完成后再触发淡入
        void question_text.offsetWidth
        fadeIn(question_text, '.125s')
    }

    question_text.addEventListener('transitionend', onFadeOutEnd)
    fadeOut(question_text, '.125s')
}

function fadeIn(element, time = '.25s') {
    element.style.transition = `opacity ${time}, visibility ${time}`
    element.style.opacity = '1'
    element.style.visibility = 'visible'

    // 淡入完成后重置所有状态
    const onFadeInEnd = () => {
        element.removeEventListener('transitionend', onFadeInEnd)
        isAnimating = false
        freeze_input = false
    }
    element.addEventListener('transitionend', onFadeInEnd)
}

function fadeOut(element, time = '.25s') {
    element.style.transition = `opacity ${time}, visibility ${time}`
    element.style.opacity = '0'
    element.style.visibility = 'hidden'
}
优化点说明
  • 替换定时器为原生transitionend事件监听,完全保证文本更新逻辑在淡出动画真实执行完成后触发,不存在计时偏差问题
  • 新增动画状态锁isAnimating,避免短时间多次调用函数导致的动画堆叠、逻辑混乱
  • 明确指定过渡属性为opacity和visibility,避免无关属性被过渡影响,同时利用visibility的过渡特性实现状态和透明度的同步切换
  • 新增事件主动解绑逻辑,避免重复绑定事件导致的内存泄漏和逻辑异常
  • 增加重绘触发逻辑void element.offsetWidth,确保内容更新完成后再触发淡入动画,避免出现视觉跳变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 08:15:02