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

Modal滑入动画仅在打开时生效,需实现关闭时也触发该动画

解决Modal关闭时无滑出动画的问题

当前代码中,关闭Modal时直接设置modal.style.display = "none"会让元素瞬间隐藏,导致关闭动画根本无法执行。要实现打开和关闭的双向动画,需要通过类控制状态,让动画完整执行后再隐藏元素。

修改方案

1. 新增关闭动画的CSS关键帧

2. 用CSS类控制Modal内容的动画状态

3. 监听动画结束事件,完成动画后再隐藏Modal


完整代码

HTML(无需修改)

<button id="myBtn">Open Modal</button>

<!-- The Modal -->
<div id="myModal" class="modal">

  <!-- Modal content -->
  <div class="modal-content">
    <div class="modal-header">
        <div class="container">
            <button class="close">CLOSE!!!!</button>             
        </div>
    </div>
    <div class="modal-body">
      <p>Lorem ipsum</p>
    </div>
    <div class="modal-footer">
        <div class="">
            <h3>Modal Footer</h3>
        </div>       
    </div>
  </div>

</div>

CSS(修改/新增部分标注)

.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 11; /* Sit on top */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
  animation-name: fadeIn; /* Fade in the background */
  animation-duration: 0.4s;
}

/* Modal Content */
.modal-content {
  height: 200px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: fixed;
  bottom: 0;
  background-color: white;
  width: 100%;
  animation-duration: 0.4s;
  animation-fill-mode: forwards; /* 保持动画结束后的状态 */
}

/* 新增:打开动画类 */
.modal-content.slide-in {
  animation-name: slideIn;
}

/* 新增:关闭动画类 */
.modal-content.slide-out {
  animation-name: slideOut;
}

/* 保留原有其他样式 */
.close {
  background-color: red;
  color: white;
}
.close:hover,
.close:focus {
  color: white;
  text-decoration: none;
  cursor: pointer;
  background-color: yellow;
  color: red;
}
.modal-header, .modal-footer {
    height: 60px;
    background-color: black;
    padding: 10px;
    color: white;
}

.modal-body {
  padding: 10px;
  overflow-y: scroll;
}

.modal-footer {
  color: white;
}

#editor-container {
  height: 200px;
}

/* Add Animation */
@keyframes slideIn {
  from {bottom: -300px; opacity: 0}
  to {bottom: 0; opacity: 1}
}

/* 新增:关闭动画 */
@keyframes slideOut {
  from {bottom: 0; opacity: 1}
  to {bottom: -300px; opacity: 0}
}

@keyframes fadeIn {
  from {opacity: 0}
  to {opacity: 1}
}

/* 新增:背景淡出动画 */
@keyframes fadeOut {
  from {opacity: 1}
  to {opacity: 0}
}

JS(修改/新增部分标注)

const modal = document.getElementById("myModal");
const btnFooterModal = document.getElementById("myBtn");
const btnCloseFooterModal = document.querySelector("#myModal .close");
const modalContent = modal.querySelector(".modal-content");

// 打开Modal
btnFooterModal.addEventListener('click', function() {
  modal.style.display = "block";
  // 强制浏览器重绘,确保动画每次都能触发
  void modalContent.offsetWidth;
  modalContent.classList.add("slide-in");
  modalContent.classList.remove("slide-out");
});

// 封装关闭逻辑
function closeModal() {
  // 添加关闭动画类
  modalContent.classList.add("slide-out");
  modalContent.classList.remove("slide-in");
  // 给背景添加淡出动画
  modal.style.animationName = "fadeOut";
  
  // 监听动画结束,完成后隐藏元素
  const handleAnimationEnd = () => {
    modal.style.display = "none";
    modal.style.animationName = "fadeIn"; // 重置背景动画
    modalContent.removeEventListener("animationend", handleAnimationEnd);
  };
  
  modalContent.addEventListener("animationend", handleAnimationEnd);
}

btnCloseFooterModal.addEventListener('click', closeModal);

window.onclick = function(event) {
  if (event.target == modal) {
    closeModal();
  }
}

关键说明

  • animation-fill-mode: forwards:让Modal内容保持动画结束后的状态,避免跳回初始位置
  • void modalContent.offsetWidth:强制浏览器触发重绘,解决重复打开时动画不生效的问题
  • animationend事件监听:确保关闭动画完全执行后,再隐藏Modal元素

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:11:06