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

animationend事件绑定异常排查:为何首个动画结束后即触发alert弹窗?

为什么alert在第一个动画结束后就触发了?

嗨,这个问题其实是**DOM事件冒泡(Event Bubbling)**在搞鬼!让我一步步给你捋清楚发生的全过程:

  1. 点击按钮后,你给second元素添加了4秒的动画,动画结束时会触发second的animationend事件。
  2. 由于second是one的子元素,按照DOM事件流的默认规则,这个animationend事件会向上冒泡,触发父元素one的animationend事件——哪怕这时候one还没开始动画!
  3. 而你刚好是在second的animationend回调里,才给one绑定了animationend监听函数。这时候冒泡上来的事件刚好命中这个刚绑定的函数,直接就弹出了alert,完全等不到one的动画完成。

解决方法有这几种,你可以选适合自己的:

方案一:判断事件源,确保是one自己的动画结束

在one的animationend回调里,检查触发事件的元素是不是one本身,只有符合条件才执行alert:

const overlay = document.getElementById('one');
const second = document.getElementById('second');
const mybtn = document.getElementById('mybtn');

mybtn.addEventListener('click', function(){
  second.style.animation = '4000ms ease forwards test';
  second.addEventListener("animationend", function() {
    overlay.style.animation = '4000ms ease forwards test';
    overlay.addEventListener("animationend", function(e) {
      // 确认事件来自one元素本身,而非子元素冒泡
      if(e.target === this){
        alert('hello');
      }
    });
  });
});

方案二:使用once: true让监听函数仅执行一次

给事件监听添加once: true配置,这样函数只会触发一次,既避免冒泡干扰,也不用手动移除监听:

const overlay = document.getElementById('one');
const second = document.getElementById('second');
const mybtn = document.getElementById('mybtn');

mybtn.addEventListener('click', function(){
  second.style.animation = '4000ms ease forwards test';
  second.addEventListener("animationend", function() {
    overlay.style.animation = '4000ms ease forwards test';
    overlay.addEventListener("animationend", function() {
      alert('hello');
    }, { once: true }); // 仅执行一次
  }, { once: true });
});

方案三:通过animationName判断对应动画

利用事件对象的animationName属性,确认是test动画结束时才触发alert,这样就算有其他动画也不会误触发:

const overlay = document.getElementById('one');
const second = document.getElementById('second');
const mybtn = document.getElementById('mybtn');

mybtn.addEventListener('click', function(){
  second.style.animation = '4000ms ease forwards test';
  second.addEventListener("animationend", function() {
    overlay.style.animation = '4000ms ease forwards test';
    overlay.addEventListener("animationend", function(e) {
      if(e.animationName === 'test'){
        alert('hello');
      }
    });
  });
});

简单来说,事件冒泡是DOM的默认行为,处理嵌套元素的同类事件时,一定要注意区分事件的真实来源,避免这种“提前触发”的坑~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 15:08:13