Toast组件hide动画无法正常显示问题求助
Toast隐藏动画不生效问题解决
问题分析
你的代码中Toast显示动画正常,但添加hide类后未触发淡出动画,元素直接“消失”(实际是透明但未移除,或动画未被正确触发)。核心原因有两点:
show类的动画通过forwards保留了opacity:1的状态,添加hide类时两个动画规则同时作用,浏览器无法正确触发新的动画序列。- 未监听动画结束事件,动画完成后没有处理元素的移除逻辑,导致视觉上产生“直接消失”的误解。
修复方案
方案1:用Transition替代Animation(更适合状态切换)
Transition更适配这种简单的显隐状态切换,避免多动画冲突:
修改后的CSS:
#toast-container { position: fixed; bottom: 10px; right: 10px; max-width: 25%; z-index: 15; display: flex; flex-direction: column; align-items: flex-end; } .toast { font-family: 'Roboto', sans-serif; font-size: 16px; background-color: var(--page-accent-color); padding: 10px; border-radius: 10px; opacity: 0; box-shadow: 0 0 8px rgba(0, 0, 0, 0.25); display: inline-block; margin-top: 5px; transition: opacity 0.5s ease-in-out; /* 替换为transition */ } .toast.show { opacity: 1; /* 直接设置目标状态 */ } .toast.hide { opacity: 0; } .toast-title { font-size: 18px; font-weight: bold; margin-bottom: 10px; }
修改后的JavaScript:
function showToast(title = '', message, time = 5000) { const toastContainer = document.getElementById('toast-container'); const toast = document.createElement('div'); toast.className = 'toast'; if (title) { const titleElement = document.createElement('div'); titleElement.className = 'toast-title'; titleElement.innerHTML = title; toast.appendChild(titleElement); } const messageElement = document.createElement('div'); messageElement.className = 'toast-message'; messageElement.innerHTML = message; toast.appendChild(messageElement); toastContainer.appendChild(toast); // 触发重绘确保transition生效 requestAnimationFrame(() => { toast.classList.add('show'); }); setTimeout(() => { toast.classList.add('hide'); // 监听过渡结束后移除元素 toast.addEventListener('transitionend', () => { toast.remove(); }, { once: true }); }, time); }
方案2:保留Animation,修复动画冲突
如果坚持使用Animation,需确保添加hide类时先移除show类,并监听动画结束:
修改后的JavaScript:
function showToast(title = '', message, time = 5000) { const toastContainer = document.getElementById('toast-container'); const toast = document.createElement('div'); toast.className = 'toast'; if (title) { const titleElement = document.createElement('div'); titleElement.className = 'toast-title'; titleElement.innerHTML = title; toast.appendChild(titleElement); } const messageElement = document.createElement('div'); messageElement.className = 'toast-message'; messageElement.innerHTML = message; toast.appendChild(messageElement); toastContainer.appendChild(toast); requestAnimationFrame(() => { toast.classList.add('show'); }); setTimeout(() => { // 先移除show类,再添加hide类 toast.classList.remove('show'); requestAnimationFrame(() => { toast.classList.add('hide'); }); // 监听动画结束后移除元素 toast.addEventListener('animationend', () => { toast.remove(); }, { once: true }); }, time); }
关键说明
requestAnimationFrame用于确保DOM更新完成后再触发状态变化,避免浏览器优化导致动画不生效。- 监听事件时设置
{ once: true },确保事件只触发一次,防止内存泄漏。
内容的提问来源于stack exchange,提问作者MeesterZee
相关产品推荐
相关产品推荐

