generated from dellevin/template
加入照片功能
This commit is contained in:
@@ -29,20 +29,6 @@
|
||||
|
||||
// 关闭按钮
|
||||
blogPostsClose.addEventListener('click', closeFullModal);
|
||||
|
||||
// 点击背景关闭
|
||||
blogPostsFullModal.addEventListener('click', function(e) {
|
||||
if (e.target === blogPostsFullModal) {
|
||||
closeFullModal();
|
||||
}
|
||||
});
|
||||
|
||||
// ESC 键关闭
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape' && blogPostsFullModal.classList.contains('active')) {
|
||||
closeFullModal();
|
||||
}
|
||||
});
|
||||
|
||||
// 页面加载时自动加载数据(用于 Hover 预览)
|
||||
loadBlogPosts(true);
|
||||
@@ -94,12 +80,13 @@
|
||||
const result = await response.json();
|
||||
const posts = result.data.dataSet || [];
|
||||
const totalPages = result.data.pages || 0;
|
||||
const totalCount = result.data.count || 0; // 获取总数
|
||||
|
||||
// 判断是否还有更多数据
|
||||
hasMore = currentPage < totalPages;
|
||||
|
||||
if (reset) {
|
||||
renderPosts(posts, true);
|
||||
renderPosts(posts, true, totalCount);
|
||||
} else {
|
||||
appendPosts(posts);
|
||||
}
|
||||
@@ -117,7 +104,7 @@
|
||||
}
|
||||
|
||||
// 渲染文章列表
|
||||
function renderPosts(posts, isReset = false) {
|
||||
function renderPosts(posts, isReset = false, totalCount = 0) {
|
||||
let html = '';
|
||||
|
||||
if (!posts || posts.length === 0) {
|
||||
@@ -138,6 +125,18 @@
|
||||
|
||||
if (blogPostsList) blogPostsList.innerHTML = html;
|
||||
if (blogPostsFullBody) blogPostsFullBody.innerHTML = html;
|
||||
|
||||
// 更新预览面板标题显示总数
|
||||
const previewHeader = document.querySelector('#blog-posts-preview .preview-header h3');
|
||||
if (previewHeader && totalCount > 0) {
|
||||
const lang = localStorage.getItem('preferred_language') || 'zh';
|
||||
const translations = {
|
||||
'zh': typeof translationsZH !== 'undefined' ? translationsZH : {},
|
||||
'en': typeof translationsEN !== 'undefined' ? translationsEN : {}
|
||||
};
|
||||
const titleText = translations[lang]['blog_latest_posts'] || '最新文章';
|
||||
previewHeader.textContent = `${titleText} (${totalCount})`;
|
||||
}
|
||||
}
|
||||
|
||||
// 追加文章
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
'use strict';
|
||||
|
||||
// Flask API 地址
|
||||
const API_BASE_URL = 'http://localhost:8360';
|
||||
const API_BASE_URL = 'https://comments.iletter.top';
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
let currentPage = 1;
|
||||
@@ -63,20 +63,6 @@
|
||||
// 关闭按钮
|
||||
guestbookClose.addEventListener('click', closeFullModal);
|
||||
|
||||
// 点击背景关闭
|
||||
guestbookFullModal.addEventListener('click', function(e) {
|
||||
if (e.target === guestbookFullModal) {
|
||||
closeFullModal();
|
||||
}
|
||||
});
|
||||
|
||||
// ESC 键关闭
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape' && guestbookFullModal.classList.contains('active')) {
|
||||
closeFullModal();
|
||||
}
|
||||
});
|
||||
|
||||
// 预览面板触底加载
|
||||
if (previewBody) {
|
||||
previewBody.addEventListener('scroll', handlePreviewScroll);
|
||||
@@ -217,12 +203,29 @@
|
||||
guestbookBody.innerHTML = html;
|
||||
|
||||
// 同时更新 Hover 预览面板(使用累积的所有留言)
|
||||
renderPreview(allComments);
|
||||
renderPreview(allComments, totalCount);
|
||||
}
|
||||
|
||||
// 渲染 Hover 预览面板
|
||||
function renderPreview(comments) {
|
||||
if (!previewBody || !comments || comments.length === 0) return;
|
||||
function renderPreview(comments, totalCount = 0) {
|
||||
if (!previewBody) return;
|
||||
|
||||
if (!comments || comments.length === 0) {
|
||||
previewBody.innerHTML = '<div class="guestbook-empty">暂无留言,快来抢沙发吧!</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新标题显示总数
|
||||
const previewHeader = document.querySelector('#guestbook-preview .preview-header h3');
|
||||
if (previewHeader && totalCount > 0) {
|
||||
const lang = localStorage.getItem('preferred_language') || 'zh';
|
||||
const translations = {
|
||||
'zh': typeof translationsZH !== 'undefined' ? translationsZH : {},
|
||||
'en': typeof translationsEN !== 'undefined' ? translationsEN : {}
|
||||
};
|
||||
const titleText = translations[lang]['guestbook_title'] || '留言板';
|
||||
previewHeader.textContent = `${titleText} (${totalCount})`;
|
||||
}
|
||||
|
||||
let html = '';
|
||||
comments.forEach(comment => {
|
||||
@@ -305,7 +308,7 @@
|
||||
}
|
||||
|
||||
// 更新预览面板
|
||||
renderPreview(allComments);
|
||||
renderPreview(allComments, allComments.length);
|
||||
}
|
||||
|
||||
// 渲染单个留言项
|
||||
|
||||
@@ -73,5 +73,8 @@ const translationsEN = {
|
||||
// Top-right buttons
|
||||
btn_guestbook: "Guestbook",
|
||||
btn_blog_posts: "Blog Posts",
|
||||
btn_photo_album: "Photo Album",
|
||||
blog_latest_posts: "Latest Posts",
|
||||
photo_latest_photos: "Latest Photos",
|
||||
photo_album_title: "Photo Album",
|
||||
};
|
||||
|
||||
@@ -73,5 +73,8 @@ const translationsZH = {
|
||||
// 右上角按钮
|
||||
btn_guestbook: "留言板",
|
||||
btn_blog_posts: "博客文章",
|
||||
btn_photo_album: "人生相册",
|
||||
blog_latest_posts: "最新文章",
|
||||
photo_latest_photos: "最新照片",
|
||||
photo_album_title: "人生相册",
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
let html = "";
|
||||
memos.forEach((memo) => {
|
||||
const formattedDate = formatDate(memo.displayTime);
|
||||
const formattedDate = formatDate(memo.createTime);
|
||||
const tagsHtml =
|
||||
memo.tags && memo.tags.length > 0
|
||||
? `<div class="memo-tags">${memo.tags
|
||||
|
||||
242
static/js/photo_album.js
Normal file
242
static/js/photo_album.js
Normal file
@@ -0,0 +1,242 @@
|
||||
// ==================== 人生相册功能 ====================
|
||||
(function() {
|
||||
// DOM 元素
|
||||
const photoAlbumBtn = document.getElementById('photo-album-btn');
|
||||
const photoAlbumPreview = document.getElementById('photo-album-preview');
|
||||
const photoAlbumFullModal = document.getElementById('photo-album-full-modal');
|
||||
const photoAlbumClose = document.getElementById('photo-album-close');
|
||||
const photoAlbumList = document.querySelector('.photo-album-list');
|
||||
const photoAlbumBody = document.querySelector('#photo-album-full-modal .photo-album-body');
|
||||
|
||||
// 照片数据
|
||||
let allPhotos = [];
|
||||
let currentPhotoIndex = 0; // 当前查看的照片索引
|
||||
const PHOTO_BASE_PATH = './static/img/photos/';
|
||||
|
||||
// 初始化
|
||||
function init() {
|
||||
if (!photoAlbumBtn || !photoAlbumFullModal) return;
|
||||
|
||||
// 点击按钮打开完整弹窗
|
||||
photoAlbumBtn.addEventListener('click', openFullModal);
|
||||
|
||||
// 关闭按钮
|
||||
photoAlbumClose.addEventListener('click', closeFullModal);
|
||||
|
||||
// 页面加载时自动加载照片(用于 Hover 预览)
|
||||
loadPhotos(true);
|
||||
}
|
||||
|
||||
// 加载照片
|
||||
async function loadPhotos(reset = false) {
|
||||
if (reset) {
|
||||
if (photoAlbumList) photoAlbumList.innerHTML = '<div class="guestbook-loading">正在加载照片...</div>';
|
||||
if (photoAlbumBody) photoAlbumBody.innerHTML = '<div class="guestbook-loading">正在加载照片...</div>';
|
||||
}
|
||||
|
||||
try {
|
||||
// 从 JSON 文件获取照片列表
|
||||
const response = await fetch(`${PHOTO_BASE_PATH}photos.json`);
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to load photos.json');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const photoFiles = data.photos || [];
|
||||
|
||||
allPhotos = photoFiles.map((filename, index) => ({
|
||||
id: index + 1,
|
||||
src: `${PHOTO_BASE_PATH}${encodeURIComponent(filename)}`,
|
||||
filename: filename
|
||||
}));
|
||||
|
||||
renderPhotos(allPhotos, reset);
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载照片失败:', error);
|
||||
if (reset) {
|
||||
const errorMsg = '<div class="guestbook-empty">加载照片失败,请稍后重试</div>';
|
||||
if (photoAlbumList) photoAlbumList.innerHTML = errorMsg;
|
||||
if (photoAlbumBody) photoAlbumBody.innerHTML = errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染照片列表
|
||||
function renderPhotos(photos, isReset = false) {
|
||||
let html = '';
|
||||
|
||||
if (!photos || photos.length === 0) {
|
||||
html = '<div class="guestbook-empty">暂无照片</div>';
|
||||
} else {
|
||||
// 预览面板:显示最新的几张照片
|
||||
if (isReset && photoAlbumList) {
|
||||
const previewPhotos = photos.slice(0, 5); // 只显示前5张
|
||||
let previewHtml = '<div class="photo-album-container">';
|
||||
previewPhotos.forEach((photo, index) => {
|
||||
previewHtml += `
|
||||
<div class="photo-preview-item" onclick="window.openPhotoLightbox(${index})">
|
||||
<img src="${photo.src}" alt="照片 ${photo.id}" loading="lazy">
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
previewHtml += '</div>';
|
||||
photoAlbumList.innerHTML = previewHtml;
|
||||
}
|
||||
|
||||
// 完整弹窗:瀑布流布局显示所有照片
|
||||
html = '<div class="photo-album-grid">';
|
||||
photos.forEach((photo, index) => {
|
||||
html += `
|
||||
<div class="photo-album-item" onclick="window.openPhotoLightbox(${index})">
|
||||
<img src="${photo.src}" alt="照片 ${photo.id}" loading="lazy">
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
if (photoAlbumBody) photoAlbumBody.innerHTML = html;
|
||||
}
|
||||
|
||||
// 打开完整弹窗
|
||||
function openFullModal() {
|
||||
photoAlbumFullModal.classList.add('active');
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
// 关闭完整弹窗
|
||||
function closeFullModal() {
|
||||
photoAlbumFullModal.classList.remove('active');
|
||||
document.body.style.overflow = '';
|
||||
}
|
||||
|
||||
// 打开照片放大查看器
|
||||
window.openPhotoLightbox = function(photoIndex) {
|
||||
currentPhotoIndex = photoIndex;
|
||||
|
||||
// 检查是否已经存在 lightbox
|
||||
let lightbox = document.querySelector('.photo-lightbox');
|
||||
if (!lightbox) {
|
||||
lightbox = document.createElement('div');
|
||||
lightbox.className = 'photo-lightbox';
|
||||
lightbox.innerHTML = `
|
||||
<span class="photo-lightbox-close">×</span>
|
||||
<span class="photo-lightbox-nav photo-lightbox-prev">❮</span>
|
||||
<img src="" alt="放大照片">
|
||||
<span class="photo-lightbox-nav photo-lightbox-next">❯</span>
|
||||
<div class="photo-lightbox-counter"></div>
|
||||
`;
|
||||
document.body.appendChild(lightbox);
|
||||
|
||||
// 点击关闭按钮
|
||||
lightbox.querySelector('.photo-lightbox-close').addEventListener('click', closePhotoLightbox);
|
||||
|
||||
// 点击背景关闭
|
||||
lightbox.addEventListener('click', function(e) {
|
||||
if (e.target === lightbox) {
|
||||
closePhotoLightbox();
|
||||
}
|
||||
});
|
||||
|
||||
// 上一张按钮
|
||||
lightbox.querySelector('.photo-lightbox-prev').addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
showPreviousPhoto();
|
||||
});
|
||||
|
||||
// 下一张按钮
|
||||
lightbox.querySelector('.photo-lightbox-next').addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
showNextPhoto();
|
||||
});
|
||||
|
||||
// 键盘事件
|
||||
document.addEventListener('keydown', handleLightboxKeydown);
|
||||
}
|
||||
|
||||
// 更新图片显示
|
||||
updateLightboxImage();
|
||||
lightbox.classList.add('active');
|
||||
};
|
||||
|
||||
// 更新 Lightbox 图片
|
||||
function updateLightboxImage() {
|
||||
const lightbox = document.querySelector('.photo-lightbox');
|
||||
if (!lightbox || !allPhotos[currentPhotoIndex]) return;
|
||||
|
||||
const img = lightbox.querySelector('img');
|
||||
const counter = lightbox.querySelector('.photo-lightbox-counter');
|
||||
|
||||
// 淡出效果
|
||||
img.style.opacity = '0';
|
||||
|
||||
setTimeout(() => {
|
||||
img.src = allPhotos[currentPhotoIndex].src;
|
||||
img.alt = `照片 ${currentPhotoIndex + 1}`;
|
||||
|
||||
// 更新计数器
|
||||
if (counter) {
|
||||
counter.textContent = `${currentPhotoIndex + 1} / ${allPhotos.length}`;
|
||||
}
|
||||
|
||||
// 淡入效果
|
||||
img.onload = () => {
|
||||
img.style.opacity = '1';
|
||||
};
|
||||
}, 150);
|
||||
}
|
||||
|
||||
// 显示上一张照片
|
||||
function showPreviousPhoto() {
|
||||
if (currentPhotoIndex > 0) {
|
||||
currentPhotoIndex--;
|
||||
} else {
|
||||
currentPhotoIndex = allPhotos.length - 1; // 循环到最后一张
|
||||
}
|
||||
updateLightboxImage();
|
||||
}
|
||||
|
||||
// 显示下一张照片
|
||||
function showNextPhoto() {
|
||||
if (currentPhotoIndex < allPhotos.length - 1) {
|
||||
currentPhotoIndex++;
|
||||
} else {
|
||||
currentPhotoIndex = 0; // 循环到第一张
|
||||
}
|
||||
updateLightboxImage();
|
||||
}
|
||||
|
||||
// 处理键盘事件
|
||||
function handleLightboxKeydown(e) {
|
||||
if (e.key === 'ArrowLeft') {
|
||||
showPreviousPhoto();
|
||||
} else if (e.key === 'ArrowRight') {
|
||||
showNextPhoto();
|
||||
} else if (e.key === 'Escape') {
|
||||
closePhotoLightbox();
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭照片放大查看器
|
||||
function closePhotoLightbox() {
|
||||
const lightbox = document.querySelector('.photo-lightbox');
|
||||
if (lightbox) {
|
||||
lightbox.classList.remove('active');
|
||||
|
||||
// 移除键盘事件监听器
|
||||
document.removeEventListener('keydown', handleLightboxKeydown);
|
||||
|
||||
setTimeout(() => {
|
||||
lightbox.remove();
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
|
||||
// DOM 加载完成后初始化
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user