求助:如何实现点击放大+可切换的网格图片画廊?
实现图片画廊的点击放大与切换功能
下面是完整的实现方案,替换你现有代码即可实现点击放大、点击切换和滑动切换的效果:
完整代码
HTML
<div class="grid-container"> <div class="gallery"> <img src="https://www.w3schools.com/css/img_5terre.jpg" alt="Cinque Terre" class="gallery-img" data-index="0"> <div class="desc">Add a description of the image here</div> </div> <div class="gallery"> <img src="https://www.w3schools.com/css/img_forest.jpg" alt="Forest" class="gallery-img" data-index="1"> <div class="desc">Add a description of the image here</div> </div> <div class="gallery"> <img src="https://www.w3schools.com/css/img_lights.jpg" alt="Northern Lights" class="gallery-img" data-index="2"> <div class="desc">Add a description of the image here</div> </div> <div class="gallery"> <img src="https://www.w3schools.com/css/img_mountains.jpg" alt="Mountains" class="gallery-img" data-index="3"> <div class="desc">Add a description of the image here</div> </div> </div> <!-- 模态框(放大预览层) --> <div class="lightbox" id="lightbox"> <span class="lightbox-close">×</span> <button class="lightbox-prev">❮</button> <img class="lightbox-img" id="lightbox-img"> <button class="lightbox-next">❯</button> </div>
CSS
.grid-container { display: grid; grid-template-columns: 1fr; grid-gap: 0%; } .gallery { margin: 2%; border: 1px solid #ccc; cursor: pointer; /* 提示可点击 */ } .gallery:hover { border: 1px solid #777; color: blueviolet; } .gallery img { width: 100%; height: auto; } .desc { padding: 1%; text-align: center; } /* 模态框样式 */ .lightbox { display: none; /* 默认隐藏 */ position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.9); /* 半透明背景 */ } .lightbox-img { margin: auto; display: block; max-width: 90%; max-height: 90%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } /* 切换按钮样式 */ .lightbox-prev, .lightbox-next { position: absolute; top: 50%; transform: translateY(-50%); background-color: rgba(255,255,255,0.2); border: none; color: white; font-size: 2rem; padding: 1rem; cursor: pointer; } .lightbox-prev { left: 1rem; } .lightbox-next { right: 1rem; } .lightbox-prev:hover, .lightbox-next:hover { background-color: rgba(255,255,255,0.4); } /* 关闭按钮样式 */ .lightbox-close { position: absolute; top: 1rem; right: 2rem; color: white; font-size: 2.5rem; cursor: pointer; }
JavaScript
// 获取所有画廊图片和模态框元素 const galleryImgs = document.querySelectorAll('.gallery-img'); const lightbox = document.getElementById('lightbox'); const lightboxImg = document.getElementById('lightbox-img'); const closeBtn = document.querySelector('.lightbox-close'); const prevBtn = document.querySelector('.lightbox-prev'); const nextBtn = document.querySelector('.lightbox-next'); // 存储所有图片的src和alt const imageList = Array.from(galleryImgs).map(img => ({ src: img.src, alt: img.alt })); let currentIndex = 0; // 打开模态框 function openLightbox(index) { currentIndex = index; lightboxImg.src = imageList[index].src; lightboxImg.alt = imageList[index].alt; lightbox.style.display = 'block'; } // 关闭模态框 function closeLightbox() { lightbox.style.display = 'none'; } // 切换到上一张图片 function prevImage() { currentIndex = (currentIndex - 1 + imageList.length) % imageList.length; lightboxImg.src = imageList[currentIndex].src; lightboxImg.alt = imageList[currentIndex].alt; } // 切换到下一张图片 function nextImage() { currentIndex = (currentIndex + 1) % imageList.length; lightboxImg.src = imageList[currentIndex].src; lightboxImg.alt = imageList[currentIndex].alt; } // 绑定点击事件 galleryImgs.forEach(img => { img.addEventListener('click', () => { openLightbox(parseInt(img.dataset.index)); }); }); closeBtn.addEventListener('click', closeLightbox); prevBtn.addEventListener('click', prevImage); nextBtn.addEventListener('click', nextImage); // 点击模态框背景关闭 lightbox.addEventListener('click', (e) => { if (e.target === lightbox) { closeLightbox(); } }); // 键盘控制切换和关闭 document.addEventListener('keydown', (e) => { if (lightbox.style.display === 'block') { if (e.key === 'ArrowLeft') prevImage(); if (e.key === 'ArrowRight') nextImage(); if (e.key === 'Escape') closeLightbox(); } }); // 滑动切换支持(移动端) let touchStartX = 0; let touchEndX = 0; lightbox.addEventListener('touchstart', (e) => { touchStartX = e.changedTouches[0].screenX; }); lightbox.addEventListener('touchend', (e) => { touchEndX = e.changedTouches[0].screenX; handleSwipe(); }); function handleSwipe() { if (touchEndX < touchStartX) { // 向左滑动,下一张 nextImage(); } if (touchEndX > touchStartX) { // 向右滑动,上一张 prevImage(); } }
关键修改说明
- 移除了原有的
<a>标签,避免点击打开新标签页,改为给图片添加点击事件触发模态框 - 添加了全屏模态框(lightbox),用于显示放大后的图片
- 实现了三种切换方式:点击左右按钮、键盘方向键、移动端滑动
- 支持点击背景或ESC键关闭模态框
- 保持了原有的网格布局和画廊样式,不会超出wrapper范围
内容的提问来源于stack exchange,提问作者Ariel Jackam
相关产品推荐
相关产品推荐

