使用 JavaScript "transitionend" 事件按顺序隐藏 3 个元素不起作用?

Hiding 3 elements in sequence not working using JavaScript "transitionend" event?

什么。我有 3 个框:blueredblack,我正在尝试按以下顺序使用 JavaScript 事件侦听器一个接一个地转换它们:blackred 然后是 blue.

如何https://codepen.io/gremo/pen/XWVeQVP?editors=1010

基本HTML结构和嵌套(完整示例用笔):

<div id="container">
    <div id="blue"></div>
    <div id="red">
        <div id="black"></div>
    </div>
</div>

JavaScript代码很简单:

const blue = document.getElementById('blue');
const red = document.getElementById('red');
const black = document.getElementById('black');

const hideElement = element => {
  console.log(`Hiding element ${element.getAttribute('id')}`);
  element.classList.add(element.dataset.hideClass);
};

black.addEventListener('transitionend', () => hideElement(red)); // when black transition ends, hide the red
red.addEventListener('transitionend', () => hideElement(blue)); // when red transition ends, hide the blue
hideElement(black); // hide the black (start the chain)

问题:在 black 结束后,bluered 同时开始...这是错误的因为 blue 应该在 red 完成后开始隐藏。此外,控制台显示 bluetransitionend 事件侦听器被调用了 2 次。

非常感谢任何帮助,几天以来我一直在努力解决这个问题。

似乎因为 blackred 的 child,transitionend 事件冒泡了,导致 red 触发了两次事件:

document.addEventListener('DOMContentLoaded', () => {
  const blue = document.getElementById('blue');
  const red = document.getElementById('red');
  const black = document.getElementById('black');

  const hideElement = element => {
    console.log(`Hiding element ${element.getAttribute('id')}`);
    element.classList.add(element.dataset.hideClass);
  };

  black.addEventListener('transitionend', (e) => {
    e.stopPropagation();// <-- added this line
    hideElement(red);
  });
  red.addEventListener('transitionend', () => hideElement(blue));
  hideElement(black);
});

(由您的代码笔编辑;我懒得注册,所以无法分叉)

transitionend事件一旦执行就会触发所有的监听器。由于红色和黑色都在第一个事件触发之前都注册了事件侦听器 运行。为了防止这种情况,您可以传递一个函数,该函数将在隐藏元素函数中添加事件侦听器,或者更优选地将事件与元素一起传递并调用 stopPropagation。 stopPropagation 是一个事件函数,它将阻止事件的传播,因此在这种情况下只会触发第一个

e?.stopPropagation()

下面是一个修改后的函数,应该可以在您的上下文中使用

document.addEventListener('DOMContentLoaded', () => {
  const blue = document.getElementById('blue');
  const red = document.getElementById('red');
  const black = document.getElementById('black');

  const hideElement = (element,e) => {
    console.log(`Hiding element ${element.getAttribute('id')}`);
    e?.stopPropagation()
    element.classList.add(element.dataset.hideClass);
  };
  black.addEventListener('transitionend', (e) => hideElement(red,e));
  red.addEventListener('transitionend', (e) => hideElement(blue,e));
  hideElement(black);
});