使用 JavaScript "transitionend" 事件按顺序隐藏 3 个元素不起作用?
Hiding 3 elements in sequence not working using JavaScript "transitionend" event?
什么。我有 3 个框:blue
、red
和 black
,我正在尝试按以下顺序使用 JavaScript 事件侦听器一个接一个地转换它们:black
、red
然后是 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
结束后,blue
和 red
同时开始...这是错误的因为 blue
应该在 red
完成后开始隐藏。此外,控制台显示 blue
的 transitionend
事件侦听器被调用了 2 次。
非常感谢任何帮助,几天以来我一直在努力解决这个问题。
似乎因为 black
是 red
的 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);
});
什么。我有 3 个框:blue
、red
和 black
,我正在尝试按以下顺序使用 JavaScript 事件侦听器一个接一个地转换它们:black
、red
然后是 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
结束后,blue
和 red
同时开始...这是错误的因为 blue
应该在 red
完成后开始隐藏。此外,控制台显示 blue
的 transitionend
事件侦听器被调用了 2 次。
非常感谢任何帮助,几天以来我一直在努力解决这个问题。
似乎因为 black
是 red
的 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);
});