You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS控制元素显示隐藏时如何添加生效的过渡动画效果

过渡不生效的核心原因

你的代码里transition没有效果,本质是两个浏览器渲染逻辑的问题:

  • display属性本身不支持CSS过渡,display: none和display: block之间的切换是瞬时完成的,浏览器不会计算两个状态之间的中间过渡帧,自然不会产生动画
  • 你把transition设置和display: block的修改放在同一个同步执行逻辑里,浏览器会把这两次样式修改合并为一次重绘,根本捕获不到属性变化的初始状态,无法触发过渡流程。
可直接落地的解决方案

根据你是否需要保留display:none不占文档流的特性,可以选下面两种方案:

方案1:用支持过渡的属性替代display,性能最优

如果不需要元素隐藏时完全脱离文档流,优先用opacity+visibility组合实现显隐,这两个属性原生支持过渡,不需要额外处理帧时序,性能最好。
先给目标元素加基础CSS样式:

#popup_roadmap_info_picture_1 {
  /* 初始隐藏状态 */
  opacity: 0;
  visibility: hidden;
  /* 配置3s透明度过渡 */
  transition: opacity 3s ease;
}
#popup_roadmap_info_picture_1.show {
  /* 显示状态 */
  opacity: 1;
  visibility: visible;
}

对应的JS逻辑简化为切换类名即可,稳定性更高:

function hideOrShow1() {
  const el = document.getElementById("popup_roadmap_info_picture_1");
  el.classList.toggle("show");
}

方案2:保留display切换逻辑,拆分渲染帧触发过渡

如果你必须用display: none让元素隐藏时完全不占位置,就需要把display切换和过渡属性的修改拆分到不同渲染帧,让浏览器先识别元素的显示状态,再触发属性过渡。
修改后的JS代码如下:

function hideOrShow1() {
  const el = document.getElementById("popup_roadmap_info_picture_1");
  const isVisible = el.style.display === "block";

  if (isVisible) {
    // 隐藏时先触发透明度过渡,过渡完成后再设为display:none
    el.style.opacity = 0;
    setTimeout(() => {
      el.style.display = "none";
    }, 3000);
  } else {
    // 第一步:先将元素切为显示状态,初始透明度为0
    el.style.display = "block";
    el.style.opacity = 0;
    el.style.transition = "opacity 3s ease";
    // 在下一渲染帧修改透明度,触发过渡
    requestAnimationFrame(() => {
      el.style.opacity = 1;
    });
  }
}

注意:不要给display属性加过渡,所有现代浏览器都不支持这个属性的动画效果,不要在这个方向浪费时间调试。


内容的提问来源于stack exchange,提问作者user16430735

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 05:12:16