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

使用setTimeout关闭带动画模态框后立即点击无法打开问题咨询

问题根因

  • 定时器冲突:触发关闭模态框后,setTimeout 会在2秒后执行将模态框设为display: none的逻辑,若在这2秒内重新打开模态框,刚被设为display: initial的模态框会被后续触发的旧定时器回调再次设为隐藏,导致必须等定时器执行完毕才能正常打开。
  • 透明元素拦截点击:淡出动画执行期间,模态框仅opacity变为0,实际仍以最高层级悬浮在页面上方,会拦截所有下层元素的点击事件。你观察到的仅点击原图片区域可正常触发的现象,是因为该区域对应的slide仍绑定了点击关闭事件,点击后会二次触发关闭逻辑,其他区域的模态框背景无绑定事件,点击无响应。

修复方案

方案1:最小改动修复现有逻辑

  1. 新增全局定时器变量,打开模态框时清空未执行的关闭定时器,避免旧逻辑覆盖新操作:
// 全局新增
let closeTimer = null;

// closeModal内修改setTimeout赋值
closeTimer = setTimeout( () => {
  $("#my_modal").style.display = "none";
  for (let i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }
}, 1998);

// openModal最开头新增清定时器逻辑
clearTimeout(closeTimer);
  1. 淡出时禁用模态框的点击响应,避免透明元素拦截下层点击:
// closeModal内设置fadeOut时新增
$(".fade").style.pointerEvents = "none";

// openModal内设置fadeIn时新增
$(".fade").style.pointerEvents = "auto";

方案2:更规范的动画实现(推荐)

用CSS Transition + transitionend事件替代Keyframe动画 + 固定时长setTimeout,逻辑更稳定,无定时器冲突问题:

  1. 替换CSS动画相关代码:
/* 删掉原有的fadeIn、fadeOut keyframe和animation-duration配置,替换为以下代码 */
.fade {
  transition: opacity 2s ease;
  opacity: 0;
  pointer-events: none;
}
.fade.active {
  opacity: 1;
  pointer-events: auto;
}
  1. 重写开闭模态框的动画逻辑:
const closeModal = evt => {
  for ( let i in slides ) {
    if ( evt.target == slides[i] || evt.target == $("#close_button") ) {
      const fadeEl = $(".fade");
      // 移除active类触发淡出
      fadeEl.classList.remove("active");
      // 监听过渡结束事件,执行关闭逻辑,仅触发一次
      fadeEl.addEventListener("transitionend", () => {
        $("#my_modal").style.display = "none";
        slides.forEach(slide => slide.style.display = "none");
      }, { once: true });
      
      // 原有其他逻辑不变:恢复滚动、恢复tab索引、暂停视频等
      $("body").style.overflow = "initial";
      for (let i = 0; i < gallery.length; i++) {
        gallery[i].setAttribute("tabindex", "1");
      }
      const videos = $all(".video_slides video");
      for (let p = 0; p < videos.length; p++) {
        videos[p].pause();
      }
    }
  }
}

const openModal = evt => {
  for ( let i in gallery ) {
    if ( evt.currentTarget == gallery[i] ) {
      $("body").style.overflow = "hidden";
      for (let t = 0; t < gallery.length; t++) {
        gallery[t].removeAttribute("tabindex");
      }

      $("#my_modal").style.display = "initial";
      // 下一帧添加active类,触发淡入动画
      requestAnimationFrame(() => {
        $(".fade").classList.add("active");
      });

      slides[i].style.display = "initial";
      slides[i].addEventListener("click", closeModal);
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:06:10