CSS fade with JS callback to set css display on completion interrupts animation
CSS fade with JS callback to set css display on completion interrupts animation
编辑:JSFiddle 根据要求:https://jsfiddle.net/5anz0kgt/1/
编辑2:看来动画中断实际上与元素的顺序有关...如果新banenr层在旧层之上,动画会很流畅。如果新横幅在下方,则动画会显得断断续续。
因此,新问题变成了为什么,我该如何解决?
我目前正在完成一个小横幅,但在动画方面遇到了一些问题。
最初,我只有以下控制横幅可见性和动画的功能(有效):
function fadeOut(el){
el.style.transition = "opacity 0.5s linear 0s";
el.style.opacity = 0;
}
function fadeIn(el){
el.style.transition = "opacity 0.5s linear 0s";
el.style.opacity = 1;
}
但我很快注意到,由于元素堆叠,这(当然)使横幅上的按钮无法点击。
因此我决定在不可见的横幅层上设置显示:none。为了淡入,我简单地添加了
el.style.display = "";
但为了淡出,我需要确保 css 动画在隐藏图层之前完成。所以我添加了(由 http://davidwalsh.name/css-animation-callback 提供):
var transitionEvent = whichTransitionEvent(el);
transitionEvent && el.addEventListener(transitionEvent, function() {
el.style.display = "none";
});
到 fadeOut() 函数的结尾。现在的问题是过渡现在非常突然(大部分时间 - 它似乎只在一小部分时间起作用)。
仅保留 fadeIn() 中的显示代码有效,指向 fadeOut() 更改作为问题。然而,在 firebug 中观察,我可以看到只有在不透明度动画完成后显示变化才会起作用。
我如何确保我的显示代码不会中断动画,或者我还能如何解决元素堆叠问题?
好的,我已经仔细查看了您的代码。我通过在 fadeOut/fadeIn 函数中设置 z-index 来修复过渡问题,以确保正确的元素在顶部可见,而不管堆叠如何。
此外,还有一个bug。无论用户输入如何,动画循环都会继续,因此用户交互和自动循环相互对抗,要解决这个问题,您可以使用 clearInterval 来停止 setInterval 函数(在这种情况下特别是动画循环)。
这里有一个 jsfiddle 演示了以上两个 https://jsfiddle.net/Lmtpw6yq/3/
请注意,我添加了另一个函数 select_banner,它被称为 onClick 而不是 activate_banner,以便可以中断动画循环:
// stores ID of current animation loop setInterval so can interrupt
var animationTick;
function select_banner(banner_id) {
if (animationTick) {
// stop animation loop
window.clearInterval(animationTick);
}
activate_banner(banner_id);
animation_loop();
}
通过调用 setInterval 将 animationTick 设置为动画循环函数中当前 setInterval tick 的 ID:
function animation_loop() {
animationTick = setInterval(function(){
...
}, 3000);
}
最后要注意的是 while 循环。它们有效但效率极低,首先你重复使用 getElementById 来查找相同的元素导致你的 js 一遍又一遍地遍历 dom 不必要的。此外,您打破 while 循环的条件(即搜索不存在的 ID)会导致 js 检查文档中不理想的每个节点的 ID。
由于横幅的数量没有改变,最好一次找到所有横幅并在开始时将对它们的引用存储在一个数组中,然后使用 for 循环遍历数组而不是 while 循环。
编辑:JSFiddle 根据要求:https://jsfiddle.net/5anz0kgt/1/
编辑2:看来动画中断实际上与元素的顺序有关...如果新banenr层在旧层之上,动画会很流畅。如果新横幅在下方,则动画会显得断断续续。 因此,新问题变成了为什么,我该如何解决?
我目前正在完成一个小横幅,但在动画方面遇到了一些问题。
最初,我只有以下控制横幅可见性和动画的功能(有效):
function fadeOut(el){
el.style.transition = "opacity 0.5s linear 0s";
el.style.opacity = 0;
}
function fadeIn(el){
el.style.transition = "opacity 0.5s linear 0s";
el.style.opacity = 1;
}
但我很快注意到,由于元素堆叠,这(当然)使横幅上的按钮无法点击。
因此我决定在不可见的横幅层上设置显示:none。为了淡入,我简单地添加了
el.style.display = "";
但为了淡出,我需要确保 css 动画在隐藏图层之前完成。所以我添加了(由 http://davidwalsh.name/css-animation-callback 提供):
var transitionEvent = whichTransitionEvent(el);
transitionEvent && el.addEventListener(transitionEvent, function() {
el.style.display = "none";
});
到 fadeOut() 函数的结尾。现在的问题是过渡现在非常突然(大部分时间 - 它似乎只在一小部分时间起作用)。
仅保留 fadeIn() 中的显示代码有效,指向 fadeOut() 更改作为问题。然而,在 firebug 中观察,我可以看到只有在不透明度动画完成后显示变化才会起作用。
我如何确保我的显示代码不会中断动画,或者我还能如何解决元素堆叠问题?
好的,我已经仔细查看了您的代码。我通过在 fadeOut/fadeIn 函数中设置 z-index 来修复过渡问题,以确保正确的元素在顶部可见,而不管堆叠如何。
此外,还有一个bug。无论用户输入如何,动画循环都会继续,因此用户交互和自动循环相互对抗,要解决这个问题,您可以使用 clearInterval 来停止 setInterval 函数(在这种情况下特别是动画循环)。
这里有一个 jsfiddle 演示了以上两个 https://jsfiddle.net/Lmtpw6yq/3/ 请注意,我添加了另一个函数 select_banner,它被称为 onClick 而不是 activate_banner,以便可以中断动画循环:
// stores ID of current animation loop setInterval so can interrupt
var animationTick;
function select_banner(banner_id) {
if (animationTick) {
// stop animation loop
window.clearInterval(animationTick);
}
activate_banner(banner_id);
animation_loop();
}
通过调用 setInterval 将 animationTick 设置为动画循环函数中当前 setInterval tick 的 ID:
function animation_loop() {
animationTick = setInterval(function(){
...
}, 3000);
}
最后要注意的是 while 循环。它们有效但效率极低,首先你重复使用 getElementById 来查找相同的元素导致你的 js 一遍又一遍地遍历 dom 不必要的。此外,您打破 while 循环的条件(即搜索不存在的 ID)会导致 js 检查文档中不理想的每个节点的 ID。
由于横幅的数量没有改变,最好一次找到所有横幅并在开始时将对它们的引用存储在一个数组中,然后使用 for 循环遍历数组而不是 while 循环。