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

无jQuery实现图片追加至模态查看器后放回原容器的方法

问题排查

两个bug的直接诱因:

  • 事件绑定范围错误:document.querySelector("img")仅匹配DOM中第一个<img>节点,其余图片未绑定点击监听,自然无法触发查看逻辑;同时代码中判断模态框显隐时误用赋值符=代替全等判断符===,导致显隐判断逻辑完全失效。
  • 节点还原逻辑缺失:关闭模态框时仅将图片节点从查看器中移除,未记录图片原始位置信息,无法将节点插回原位置,直接导致画廊出现空位。
修复逻辑
  • 遍历所有图片节点统一绑定点击事件,不再只选中第一张图
  • 打开模态框时,记录当前点击的图片、图片的原始父容器、图片在原位置的下一个相邻兄弟节点,用于后续精准归位
  • 修复显隐判断的符号错误,关闭模态框时将图片按记录的位置插回原容器,同时重置图片样式,避免样式污染
  • 全程使用原生DOM API实现,无jQuery依赖
修复后完整代码

JS部分

// 选中所有图片、模态框、关闭按钮
const allImgs = document.querySelectorAll(".container img");
const viewer = document.getElementById("viewer");
const closeBtn = document.getElementById("closeViewer");
// 全局存储当前激活的图片和位置信息
let activeImg = null;
let originalParent = null;
let originalNextSibling = null;

// 给所有图片绑定点击事件
allImgs.forEach(img => {
  img.addEventListener("click", viewImg);
});

function viewImg(e) {
  // 修正判断逻辑:全等判断模态框是否隐藏,单等号是赋值不是比较
  if (viewer.style.visibility !== "visible") {
    activeImg = e.target;
    originalParent = activeImg.parentNode;
    originalNextSibling = activeImg.nextSibling;
    // 把图片移到查看器
    viewer.appendChild(activeImg);
    activeImg.style.width = "60%";
    viewer.style.visibility = "visible";
  }
}

function closeViewer() {
  if (viewer.style.visibility === "visible") {
    viewer.style.visibility = "hidden";
    // 把图片插回原位置:如果原来有下一个兄弟节点,就插在它前面,否则直接追加到原容器末尾
    if (originalNextSibling) {
      originalParent.insertBefore(activeImg, originalNextSibling);
    } else {
      originalParent.appendChild(activeImg);
    }
    // 重置图片样式,回到画廊里的默认尺寸
    activeImg.style.width = "100%";
    // 清空临时存储的节点信息
    activeImg = null;
    originalParent = null;
    originalNextSibling = null;
  }
}

// 绑定关闭按钮事件
closeBtn.addEventListener("click", closeViewer);
// 可选:点击模态框遮罩层也能关闭,不需要可以删除
viewer.addEventListener("click", (e) => {
  if (e.target === viewer) {
    closeViewer();
  }
});

CSS部分(修正了原代码无效属性和颜色写法错误)

.container {
  line-height: 0;
  column-count: 3;
  column-gap: 0;
  column-fill: balance;
}

.container img {
  width: 100%;
}

.container img:hover {
  scale: 1.1;
  transition: 0.5s;
  cursor: pointer;
}

.viewer {
  visibility: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  /* 修正原代码颜色值写法,透明背景需用rgba */
  background: rgba(255, 0, 0, 0.5);
}

.closeViewer {
  color: #000;
  background: rgba(255, 255, 255, 0.5);
  position: absolute;
  top: 100px;
  right: 100px;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 3rem;
  padding: 0 10px;
  cursor: pointer;
  border: none;
}

HTML部分(移除冗余内联事件,其余结构保持不变)

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>simple gallery</title>
  <link rel="stylesheet" href="test.css">
</head>
<body>
  <div class="container" id="container">
    <img class="img" src="https://images.freeimages.com/images/large-previews/a31/colorful-umbrella-1176220.jpg">
    <img class="img" src="https://images.freeimages.com/images/large-previews/9e6/abstract-polygonal-low-poly-photos-texture-3-636190.jpg">
    <img class="img" src="https://images.freeimages.com/images/large-previews/aa8/evening-01-1055813.jpg">
    <img class="img" src="https://live.staticflickr.com/3437/3403778548_15f48ab99e_b.jpg">
    <img class="img" src="https://cdn.pixabay.com/photo/2017/07/25/01/22/cat-2536662_960_720.jpg">
    <img class="img" src="https://cdn.pixabay.com/photo/2018/08/01/19/35/wolf-3577956_960_720.jpg">
    <img class="img" src="https://live.staticflickr.com/3437/3403778548_15f48ab99e_b.jpg">
    <img class="img" src="https://cdn.pixabay.com/photo/2017/07/25/01/22/cat-2536662_960_720.jpg">
    <img class="img" src="https://cdn.pixabay.com/photo/2018/08/01/19/35/wolf-3577956_960_720.jpg">
    <img class="img" src="https://images.freeimages.com/images/large-previews/a31/colorful-umbrella-1176220.jpg">
    <img class="img" src="https://images.freeimages.com/images/large-previews/9e6/abstract-polygonal-low-poly-photos-texture-3-636190.jpg">
    <img class="img" src="https://images.freeimages.com/images/large-previews/aa8/evening-01-1055813.jpg">
  </div>

  <div class="viewer" id="viewer">
    <button class="closeViewer" id="closeViewer">X</button>
  </div>

  <script src="./test.js"></script>
</body>
</html>
关键实现说明
  • 用nextSibling记录原位置的参考节点,配合insertBefore可以100%还原图片在瀑布流中的原始位置,不会出现排序错乱
  • 图片移回原容器后主动重置width样式,避免模态框里设置的60%宽度被带回画廊,导致布局错乱
  • 删掉了原CSS中无效的left:120%属性(未给img设置定位时left属性不生效),给模态框补充left:0避免fixed定位偏移

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:12:41