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

使用Jekyll和Bootstrap的模态弹窗仅显示最后一项内容的问题排查

问题根源分析

你遇到的核心问题一眼就能看出来——循环生成的所有弹窗和触发按钮都共用了相同的类名,点击任意一个「Open」按钮时,jQuery会给所有.popup-content和.popup-overlay添加active类。由于DOM中后面的元素会覆盖前面的,所以你看到的永远是最后一个stone的内容。

修复方案

我们需要给每个弹窗和对应的触发按钮绑定唯一标识,让点击事件只作用于对应的弹窗,一步步来改:

1. 修正HTML结构(添加唯一标识)

先调整循环里的代码,给每个弹窗容器加唯一ID,同时给触发按钮添加data-target属性关联对应的弹窗:

{% for stone in site.data.stones %}
  <!-- 每个stone对应唯一的遮罩层 -->
  <div class="popup-overlay" id="overlay-{{ stone.gem | slugify }}">
    <!-- 每个stone对应唯一的弹窗内容 -->
    <div class="popup-content" id="content-{{ stone.gem | slugify }}">
      <h1>{{ stone.color }}</h1>
      <button class="close" data-target="{{ stone.gem | slugify }}">Close</button>
    </div>
  </div>
  <!-- 触发弹窗的卡片 -->
  <div class="popup-hold">
    <h1>{{ stone.gem }}</h1>
    <button class="open" data-target="{{ stone.gem | slugify }}">Open</button>
  </div>
{% endfor %}

这里用stone.gem | slugify生成安全的唯一标识(自动把特殊字符转成连字符,避免ID格式问题),每个按钮的data-target对应弹窗的ID前缀。

2. 修改jQuery逻辑(关联按钮与对应弹窗)

更新JS代码,点击按钮时通过data-target精准找到对应的弹窗,而不是操作所有同类别名的元素:

$(document).ready(function(e) {
  // 打开弹窗:获取当前按钮的target,只激活对应弹窗和遮罩
  $(".open").on("click", function(){
    const target = $(this).data('target');
    $(`#overlay-${target}, #content-${target}`).addClass("active");
  });

  // 关闭弹窗:获取当前按钮的target,只移除对应弹窗和遮罩的active类
  $(".close").on("click", function(){
    const target = $(this).data('target');
    $(`#overlay-${target}, #content-${target}`).removeClass("active");
  });

  // 点击遮罩关闭当前弹窗
  $(".popup-overlay").on("click", function(){
    $(this).removeClass("active");
    $(this).find(".popup-content").removeClass("active");
  });
});

这里的关键改动:

  • 用$(this).data('target')拿到当前点击按钮对应的唯一标识
  • 通过模板字符串$(#overlay-${target})精准定位到对应弹窗元素
  • 点击遮罩时直接操作当前遮罩及其子元素,不需要额外标识

3. CSS优化(可选,提升体验)

你的基础CSS没问题,建议把遮罩层改成固定定位,让弹窗始终居中显示:

.popup-overlay {
  visibility: hidden;
  position: fixed; /* 替换absolute为fixed */
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.5); /* 半透明灰更友好 */
  display: flex;
  align-items: center;
  justify-content: center;
}
.popup-content {
  visibility: hidden;
  background: white;
  padding: 2rem;
  border-radius: 8px;
}
/* 保留你原来的其他样式 */
.popup-content.active { visibility: visible; z-index: 1; }
.popup-hold { height: 330px; border: 2px solid black; }
为什么原来的代码不行?

原来的$(".popup-overlay, .popup-content").addClass("active")会选中DOM中所有带这些类名的元素,循环生成的3个弹窗会同时被激活,而最后一个弹窗在DOM树最下方,会显示在最上层,看起来就像所有按钮都打开同一个弹窗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:59:53