v1.4 — Photo 详情页画廊

- 灯箱画廊:点击图片全屏查看,多图左右切换
- 单图隐藏左右箭头,边界隐藏对应方向键
- 画廊顶部显示'标题 · 作者'
- 文章导航保留在灯箱底部
- 图片去重(特色图与正文图片不重复)
- 纯黑背景
- 已知限制:画廊内切换文章后灯箱不保持(AJAX 模式未稳定)
This commit is contained in:
2026-05-04 01:44:56 +08:00
parent c615206e88
commit 55cfd26162
4 changed files with 230 additions and 12 deletions
+133 -10
View File
@@ -1,18 +1,53 @@
<?php get_header(); ?>
<?php while (have_posts()) : the_post(); ?>
<div class="photo-detail">
<?php
// 收集所有图片 URL(去重)
$gallery = array();
$seen = array();
// 正文中的图片(先收,因为特色图和正文第一张可能重复)
$content_raw = get_the_content();
if (preg_match_all('/<img[^>]+src="([^"]+)"/', $content_raw, $m)) {
foreach ($m[1] as $url) {
$key = basename(parse_url($url, PHP_URL_PATH));
if (!isset($seen[$key])) {
$seen[$key] = true;
$gallery[] = $url;
}
}
}
// 特色图(如果没有出现在正文中则加入)
if (has_post_thumbnail()) {
$thumb_url = get_the_post_thumbnail_url(null, 'large');
$key = basename(parse_url($thumb_url, PHP_URL_PATH));
if (!isset($seen[$key])) {
$gallery[] = $thumb_url;
}
}
$gallery_json = json_encode($gallery);
$content = $content_raw;
?>
<div class="photo-detail" id="photo-detail"
data-gallery="<?php echo esc_attr($gallery_json); ?>"
data-title="<?php echo esc_attr(get_the_title()); ?>"
data-author="<?php echo esc_attr(get_avatar(get_the_author_meta('ID'), 18) . ' ' . get_the_author_meta('display_name')); ?>">
<a href="/photos/" class="back-link">← 返回拾影</a>
<div class="photo-detail__image">
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail('medium_large', array('alt' => get_the_title())); ?>
<?php endif; ?>
<?php // 多图文章的特色图已在正文中,不重复显示
if (!preg_match('/<img[^>]+src=/', $content) && has_post_thumbnail()) : ?>
<div class="photo-detail__image" onclick="openPhotoGallery(0)">
<?php the_post_thumbnail('medium_large', array('alt' => get_the_title())); ?>
</div>
<?php endif; ?>
<?php if (get_the_content()) : ?>
<?php if ($content) : ?>
<div class="photo-detail__body">
<?php the_content(); ?>
<?php
// 图片换成可点击版本
$content = preg_replace('/<img[^>]+src="([^"]+)"[^>]*>/', '<img src="$1" alt="" onclick="event.stopPropagation(); openPhotoImage(\'' . esc_js('$1') . '\')" />', $content);
echo $content;
?>
</div>
<?php endif; ?>
@@ -27,9 +62,8 @@
</div>
<?php
// 拾影列表按日期从新到旧,导航遵循同一方向
$left = get_adjacent_post(false, '', false); // 更新的(列表左侧)
$right = get_adjacent_post(false, '', true); // 更早的(列表右侧)
$left = get_adjacent_post(false, '', false);
$right = get_adjacent_post(false, '', true);
if ($left || $right) : ?>
<div class="photo-detail__nav">
<?php if ($left) : ?>
@@ -45,4 +79,93 @@
</div>
<?php endwhile; ?>
<!-- 照片灯箱 — 文章导航内联,不跳页面 -->
<div class="photo-lightbox" id="photo-lightbox" onclick="closePhotoLightbox()">
<span class="photo-lightbox__brand"><?php bloginfo('name'); ?></span>
<span class="photo-lightbox__close" onclick="closePhotoLightbox()">&times;</span>
<span class="photo-lightbox__counter" id="photo-lightbox-counter"></span>
<span class="photo-lightbox__nav photo-lightbox__prev" onclick="event.stopPropagation(); navigatePhoto(-1)"></span>
<span class="photo-lightbox__nav photo-lightbox__next" onclick="event.stopPropagation(); navigatePhoto(1)"></span>
<div onclick="event.stopPropagation()">
<div class="photo-lightbox__info" id="photo-lightbox-info"></div>
<div class="photo-lightbox__content">
<img id="photo-lightbox-img" src="" alt="">
</div>
</div>
<div class="photo-lightbox__postnav" id="photo-lightbox-postnav"></div>
</div>
<script>
(function() {
var detail = document.getElementById('photo-detail');
if (!detail) return;
var gallery = JSON.parse(detail.getAttribute('data-gallery') || '[]');
var lb = document.getElementById('photo-lightbox');
var lbImg = document.getElementById('photo-lightbox-img');
var lbCounter = document.getElementById('photo-lightbox-counter');
var idx = 0;
window.openPhotoGallery = function(i) {
idx = i;
show();
updateNavButtons();
updatePhotoInfo();
lb.classList.add('active');
document.body.style.overflow = 'hidden';
showPostNav();
};
function updatePhotoInfo() {
var info = document.getElementById('photo-lightbox-info');
if (!info) return;
var title = detail.getAttribute('data-title') || '';
var author = detail.getAttribute('data-author') || '';
// 提取作者纯文本(去掉 img 标签)
var tmp = document.createElement('div');
tmp.innerHTML = author;
var author_text = tmp.textContent.trim();
info.innerHTML = '<span class="photo-lightbox__photo-title">' + title + ' · ' + author_text + '</span>';
}
window.openPhotoImage = function(url) {
var i = gallery.indexOf(url);
if (i >= 0) openPhotoGallery(i);
else { idx = -1; lbImg.src = url; lbCounter.textContent = ''; lb.classList.add('active'); document.body.style.overflow = 'hidden'; }
};
window.navigatePhoto = function(d) {
idx = (idx + d + gallery.length) % gallery.length;
show();
};
window.closePhotoLightbox = function() {
lb.classList.remove('active');
document.body.style.overflow = '';
};
function showPostNav() {
var nav = document.querySelector('.photo-detail__nav');
var pn = document.getElementById('photo-lightbox-postnav');
if (nav && pn) pn.innerHTML = nav.innerHTML;
}
function show() {
lbImg.src = gallery[idx];
lbCounter.textContent = gallery.length > 1 ? (idx + 1) + ' / ' + gallery.length : '';
updateNavButtons();
}
function updateNavButtons() {
var prev = lb.querySelector('.photo-lightbox__prev');
var next = lb.querySelector('.photo-lightbox__next');
if (gallery.length <= 1) {
prev.style.display = 'none';
next.style.display = 'none';
} else {
prev.style.display = idx > 0 ? '' : 'none';
next.style.display = idx < gallery.length - 1 ? '' : 'none';
}
}
document.addEventListener('keydown', function(e) {
if (!lb.classList.contains('active')) return;
if (e.key === 'ArrowLeft') navigatePhoto(-1);
if (e.key === 'ArrowRight') navigatePhoto(1);
if (e.key === 'Escape') closePhotoLightbox();
});
})();
</script>
<?php get_footer(); ?>