手写WordPress手风琴:淡入正常淡出失效 如何正确触发淡入淡出过渡?
手风琴淡出效果失效的解决方法
为什么你的淡出效果完全不生效
核心问题出在显隐的实现逻辑上:
- 你点击收起面板的时候,JS直接把
.panel的display设为none,浏览器会立刻把这个元素从页面渲染树中移除,所有绑定在元素上的动画、过渡效果都会被直接跳过,根本没有留出播放淡出动画的时间窗口。 - 你把
fadeIn动画直接绑在默认的.panel类上,只有元素刚从display:none切换为可渲染状态的时候,才会触发一次动画。整个逻辑里根本没有给淡出动画留触发的时机。
这也是为什么你能看到淡入效果正常——刚把元素从display:none切出来的时候,元素是可被浏览器渲染的,绑定的动画能正常播放;但切回display:none的时候,元素瞬间消失,哪怕写了fadeOut动画也根本跑不起来。
新手友好的可落地方案
不用折腾复杂的动画队列和回调,靠CSS原生的过渡(transition)就能实现丝滑的淡入淡出+折叠效果,逻辑简单不容易出bug,直接适配WordPress的主题自定义代码环境,步骤如下:
第一步 改造CSS样式
- 移除
.panel上的display:none和默认绑定的fadeIn动画——display属性天生不支持平滑过渡,用它控制显隐永远做不出流畅的动画。 - 给
.panel写好默认的隐藏状态,同时给所有需要变化的属性加上过渡声明:.panel { padding: 0; max-height: 0; opacity: 0; overflow: hidden; /* 统一给所有可变化的属性加0.2s的平滑过渡,和你原来的动画时长保持一致 */ transition: all 0.2s ease-in; } - 单独加一个类标记面板的展开状态,让默认样式和展开样式产生差值,浏览器会自动在两个状态切换的时候播放平滑过渡:
注意这里的max-height值要设得比你实际页面里面板的内容高度大,不然会出现展开后内容被截断的问题,这套写法已经能实现你想要的“从上方轻微位移+淡入”的效果,不需要额外写@keyframes动画。.panel.open { padding: 10px 0; max-height: 500px; opacity: 1; }
第二步 改造JS交互逻辑
- 别再直接手动修改
panel.style.display了,改成给面板切换上面写的open类即可:var acc = document.getElementsByClassName("accordion"); var i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { this.classList.toggle("active"); var panel = this.nextElementSibling; // 只要切换open类,CSS会自动处理展开、收起的全流程过渡效果 panel.classList.toggle("open"); }); }
额外注意
如果你一定要保留原来写的fadeIn/fadeOut关键帧动画来实现效果,必须调整逻辑:点击收起的时候,先给面板加上fadeOut的动画类,等动画完整播放结束(大概0.2s),再把元素的display设为none。但这种写法需要监听动画结束的回调、还要处理连续快速点击的状态错乱问题,对新手来说门槛高,不如上面的过渡写法稳定。
内容的提问来源于stack exchange,提问作者cyrusse
相关产品推荐
相关产品推荐

