【发布时间】:2019-12-02 01:33:15
【问题描述】:
我正在尝试实现与 jQuery 的 fadeIn() 函数相同的效果,其中显示一个元素,然后它的不透明度从 0 变为 1。我需要以编程方式(不使用 jQuery)来实现,我需要能够淡出 (display:none) 然后淡入的元素。
理想的解决方案将使用 CSS 过渡来利用硬件加速 - 我可以通过收听 transitionend 事件使元素成功淡出。然而,淡入淡出被证明是一个挑战,因为以下代码没有按预期工作:
fader.style.transition = 'opacity 1s';
const fadeIn = () => {
fader.style.display = 'block';
fader.style.opacity = 1;
};
当fadeIn() 被调用时,元素只是简单地重新插入,而不是平滑地动画。我有一个codePen that I've been tinkering with 来说明问题。
我的理论是过渡无法在不在 DOM 中的元素上执行,因为我可以通过设置 height:0 而不是 display:none 来使动画工作。也许在我设置 fader.style.display = 'block'; 和 DOM 实际更新之间存在延迟,在此期间我无法转换?
关于这个想法:我似乎也可以通过使用setTimeout(() => {fader.style.opacity = 1}, 20} 延迟不透明度更改来使动画正常工作。然而,这似乎会产生一种竞争条件,因为随着超时持续时间越来越接近 0,动画的效果会越来越不可靠。
请注意,我不想像this question 的解决方案那样切换visibility 属性,因为这不会有效地从DOM 中删除元素。
将高度/宽度更改为 0 是一个更可行的选择,但由于元素的高度和宽度未知,因此需要在淡出之前捕获这些值的额外步骤,以便可以在以下情况下重新应用它们淡入。例如,如果应用程序的不同部分尝试更改这些值(例如媒体查询,并且用户在隐藏元素时旋转他们的设备),这似乎很脆弱
【问题讨论】:
-
由于您的元素被隐藏然后显示,因此不透明度不会受到影响。在将元素设置为显示后立即使用动画或添加
requestAnimationFrame将不透明度从 0 更改为 1:块。 -
@MisterJojo 谢谢! fadeOut 的函数实际上与我的函数相同......该 fadeIn 函数,但是通过使用
setInterval动画来绕过理想的解决方案。似乎必须有一种方法来做到这一点,并利用更流畅的硬件加速 css 动画。 -
非常感谢@Kyle!我不得不深入研究 rAF,但这成功了!
标签: javascript html css transition