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

自定义通知系统setTimeout异常:仅最新通知执行反向动画

解决多通知触发时仅最新通知消失的问题

问题根源

使用innerHTML +=添加新通知时,浏览器会重新解析整个.notification-holder容器的内容,直接替换掉之前所有已存在的通知元素。这会导致旧通知上绑定的动画结束事件监听全部丢失,无法执行后续的反向动画和移除逻辑,只有最后创建的新通知能正常完成整个生命周期。

修复后的代码

JavaScript

var notificationCount = 0;
// 提前创建并缓存通知容器
const notificationHolder = document.createElement('div');
notificationHolder.className = 'notification-holder';
document.body.appendChild(notificationHolder);

function notification(content){
  notificationCount += 1;
  // 创建单个通知元素
  const notificationEl = document.createElement('div');
  notificationEl.className = 'notification';
  notificationEl.id = `notification-${notificationCount}`;
  notificationEl.innerHTML = `<p>${content}</p>`;
  
  notificationHolder.appendChild(notificationEl);
  
  // 执行入场动画
  notificationEl.style.animation = "notificationAnimate 0.2s forwards";
  
  notificationEl.addEventListener("animationend", () => {
    notificationEl.style.visibility = "visible";
    notificationEl.style.animation = "";
    setTimeout(() => {
      notificationEl.style.animation = "notificationAnimate 0.2s reverse";
      // 监听退场动画结束,完成后移除元素,once确保事件只触发一次
      notificationEl.addEventListener("animationend", () => {
        notificationEl.remove();
      }, { once: true });
    }, 1000);
  }, { once: true });
}

CSS(无需修改)

:root{
    --black: #151515;
    --white: #EDEDEE;
}

.notification-holder{
    position: absolute;
    bottom: 0px;
    right: 10px;
    padding-bottom: 10px;
    overflow: hidden;
}
.notification{
    width: 250px;
    padding: 10px;
    text-align: center;
    background-color: var(--black);
    color: var(--white);
    font-size: 14px;
    font-family: "Poppins", sans-serif;
    border-radius: 10px;
}
.notification:not(:first-of-type){
    margin-top: 10px;
}

@keyframes notificationAnimate{
    0%{
        opacity: 0;
        max-height: 1px;
        transform: translateY(100px);
        scale: 0;
    }
    100%{
        opacity: 1;
        max-height: fit-content;
        transform: translateY(0px);
        /* visibility: visible; */
        scale: 1;
    }
}

HTML(无需修改)

<html>
    <head>
    </head>
    <body>
        <button onclick="notification('Dark theme has been enabled!')">Dark theme </button>
    </body>
</html>

关键修改点

  1. 用createElement+appendChild替代innerHTML +=,避免旧通知元素被重新渲染,保留原有事件监听
  2. 给addEventListener添加{ once: true }选项,确保动画结束事件只触发一次,避免重复绑定和内存泄漏
  3. 提前创建并缓存通知容器,减少DOM查询次数,提升性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:35:28