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

Toast组件hide动画无法正常显示问题求助

Toast隐藏动画不生效问题解决

问题分析

你的代码中Toast显示动画正常,但添加hide类后未触发淡出动画,元素直接“消失”(实际是透明但未移除,或动画未被正确触发)。核心原因有两点:

  1. show类的动画通过forwards保留了opacity:1的状态,添加hide类时两个动画规则同时作用,浏览器无法正确触发新的动画序列。
  2. 未监听动画结束事件,动画完成后没有处理元素的移除逻辑,导致视觉上产生“直接消失”的误解。

修复方案

方案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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:44:53