好的,這是一個符合您需求的完整 HTML 文件,其中包含了 JavaScript 程式碼,可以直接在瀏覽器中開啟使用:
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的相簿</title>
<style>
body {
font-family: sans-serif;
margin: 0;
padding: 0;
background-color: #f0f0f0;
display: flex;
flex-direction: column;
height: 100vh; /* 使 body 佔滿整個視窗高度 */
}
#controls {
position: sticky;
top: 0;
background-color: #fff;
padding: 10px;
z-index: 10; /* 確保控制項在最上層 */
display: flex;
align-items: center;
gap: 10px;
}
#mainImageContainer {
flex-grow: 1; /* 讓圖片容器佔滿剩餘空間 */
display: flex;
justify-content: center;
align-items: center;
overflow: hidden; /* 隱藏超出範圍的部分 */
}
#mainImage {
max-width: 90%; /* 控制圖片最大寬度 */
max-height: 90%; /* 控制圖片最大高度 */
display: block; /* 移除圖片下方的空隙 */
}
#mainImageCaption{
text-align: center;
}
#thumbnailContainer {
position: sticky;
bottom: 0;
background-color: #ddd;
padding: 10px;
overflow-x: auto; /* 允許水平滾動 */
white-space: nowrap; /* 防止縮圖換行 */
z-index: 10;
}
.thumbnail {
width: 100px;
height: 100px;
margin: 5px;
cursor: pointer;
border: 2px solid transparent;
}
.thumbnail.active {
border-color: blue;
}
</style>
</head>
<body>
<div id="controls">
<label for="albumSelect">選擇相簿:</label>
<select id="albumSelect"></select>
<button id="playPauseBtn">播放</button>
<label for="intervalInput">間隔 (秒):</label>
<input type="number" id="intervalInput" value="3" min="1">
</div>
<div id="mainImageContainer">
<img id="mainImage" src="" alt="">
<div id="mainImageCaption"></div>
</div>
<div id="thumbnailContainer">
</div>
<script>
const sources = {
"my_hiking_1": {
path: "../photo_galleries/my_album_1/",
data: [
"001.jpg",
"002.jpg",
"003.jpg",
],
description: [
"001_comment",
"002_comment",
"003_comment",
]
},
"my_hiking_2": {
path: "../photo_galleries/my_album_2/",
data: [
"001.jpg",
"002.jpg",
],
description: [
"001_comment",
"002_comment",
]
},
};
const albumSelect = document.getElementById('albumSelect');
const playPauseBtn = document.getElementById('playPauseBtn');
const intervalInput = document.getElementById('intervalInput');
const mainImage = document.getElementById('mainImage');
const mainImageCaption = document.getElementById('mainImageCaption');
const thumbnailContainer = document.getElementById('thumbnailContainer');
const mainImageContainer = document.getElementById('mainImageContainer');
let currentAlbum = null;
let currentIndex = 0;
let timer = null;
let isPlaying = false;
let interval = 3000; // 預設間隔 3 秒
// 初始化相簿選項
function initAlbums() {
for (const albumName in sources) {
const option = document.createElement('option');
option.value = albumName;
option.textContent = albumName;
albumSelect.appendChild(option);
}
albumSelect.addEventListener('change', loadAlbum);
}
// 載入相簿
function loadAlbum() {
currentAlbum = albumSelect.value;
currentIndex = 0;
stopPlayback();
createThumbnails();
showImage(0); // 顯示第一張圖片
// 顯示可視範圍內的縮圖
showVisibleThumbnails();
}
// 建立縮圖
function createThumbnails() {
thumbnailContainer.innerHTML = ''; // 清空現有縮圖
if (!sources[currentAlbum]) return;
sources[currentAlbum].data.forEach((filename, index) => {
const thumbnail = document.createElement('img');
thumbnail.src = sources[currentAlbum].path + filename;
thumbnail.classList.add('thumbnail');
thumbnail.addEventListener('click', () => {
stopPlayback(); //點擊縮圖時停止播放
showImage(index);
});
thumbnailContainer.appendChild(thumbnail);
});
}
// 顯示指定索引的圖片
function showImage(index) {
if (!sources[currentAlbum] || index < 0 || index >= sources[currentAlbum].data.length) {
return; // 索引超出範圍
}
currentIndex = index;
mainImage.src = sources[currentAlbum].path + sources[currentAlbum].data[index];
mainImageCaption.textContent = sources[currentAlbum].description[index] || '';
// 更新縮圖的 active 狀態
document.querySelectorAll('.thumbnail').forEach((thumb, i) => {
thumb.classList.toggle('active', i === index);
});
// 捲動到目前圖片的縮圖
scrollToThumbnail(index);
}
//捲動到指定縮圖的可視範圍內
function scrollToThumbnail(index) {
const thumbnail = document.querySelectorAll('.thumbnail')[index];
if(thumbnail){
thumbnail.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
}
}
// 開始/繼續 播放
function startPlayback() {
if (!sources[currentAlbum]) return;
if (isPlaying) return; // 已經在播放
isPlaying = true;
playPauseBtn.textContent = '暫停';
if (currentIndex >= sources[currentAlbum].data.length)
{ currentIndex = 0; //如果已到最後一張, 從頭播放
}
showImage(currentIndex); // 顯示目前圖片
timer = setInterval(() => {
currentIndex = (currentIndex + 1) % sources[currentAlbum].data.length; // 循環播放
showImage(currentIndex);
}, interval);
}
// 暫停播放
function pausePlayback() {
isPlaying = false;
playPauseBtn.textContent = '播放';
clearInterval(timer);
}
function stopPlayback() {
pausePlayback(); // 停止計時器
}
// 控制播放/暫停
function togglePlayback() {
if (isPlaying) {
pausePlayback();
} else {
startPlayback();
}
}
// 鍵盤事件處理
function handleKeyPress(event) {
switch (event.key) {
case ' ': // 空白鍵
togglePlayback();
event.preventDefault();
break;
case 'ArrowLeft': // 左方向鍵
stopPlayback(); //先停止播放
showImage(currentIndex - 1);
break;
case 'ArrowRight': // 右方向鍵
stopPlayback(); //先停止播放
showImage(currentIndex + 1);
break;
}
}
// 更新間隔時間
function updateInterval() {
const newInterval = parseInt(intervalInput.value, 10) * 1000;
if (!isNaN(newInterval) && newInterval >= 1000) {
interval = newInterval;
// 如果正在播放,重新啟動計時器以應用新的間隔
if (isPlaying) {
pausePlayback();
startPlayback();
}
}
}
// 監聽縮圖容器的滾動事件
thumbnailContainer.addEventListener('scroll', () => {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(showVisibleThumbnails, 100); // 設定延遲
});
// 顯示可視範圍內的縮圖
function showVisibleThumbnails() {
const thumbnails = document.querySelectorAll('.thumbnail');
const containerRect = thumbnailContainer.getBoundingClientRect();
thumbnails.forEach((thumbnail) => {
const thumbnailRect = thumbnail.getBoundingClientRect();
const isVisible = (
thumbnailRect.left >= containerRect.left &&
thumbnailRect.right <= containerRect.right
);
// 根據可視性來延遲載入或隱藏縮圖
if (isVisible) {
thumbnail.style.visibility = 'visible'; // 顯示
} else {
thumbnail.style.visibility = 'hidden'; // 隱藏, 但仍占空間
}
});
}
// 初始化
initAlbums();
playPauseBtn.addEventListener('click', togglePlayback);
intervalInput.addEventListener('change', updateInterval);
document.addEventListener('keydown', handleKeyPress);
// 初始載入第一個相簿 (如果存在)
if (albumSelect.options.length > 0) {
albumSelect.value = albumSelect.options[0].value;
loadAlbum();
}
</script>
</body>
</html>
程式碼說明與重要功能解釋:
HTML 結構:
controls
: 包含下拉選單、播放/暫停按鈕、間隔時間輸入框。mainImageContainer
: 用於顯示完整大小的圖片。mainImage
: img
標籤,顯示實際的圖片。mainImageCaption
: 顯示圖片描述文字。thumbnailContainer
: 包含所有縮圖的容器,設定為水平滾動。.thumbnail
: 每個縮圖的樣式。.thumbnail.active
: 當前選中圖片的縮圖樣式。CSS 樣式:
position: sticky
將 #controls
和 #thumbnailContainer
固定在頂部和底部。#mainImageContainer
使用 flex-grow: 1
佔滿剩餘空間,並置中顯示圖片。#mainImage
設置最大寬度和高度以適應容器。.thumbnail
設定基本樣式,cursor: pointer
表示可點擊。.thumbnail.active
為選中的縮圖加上邊框。JavaScript 功能:
sources
: 定義相簿資料,包含路徑、圖片檔名、描述。
變數宣告: 取得 HTML 元素,並初始化變數。
initAlbums()
: 動態產生下拉選單的選項。
loadAlbum()
:
currentAlbum
。currentIndex
為 0。createThumbnails()
建立縮圖。showImage(0)
顯示第一張圖片。showVisibleThumbnails()
顯示可視範圍內的縮圖。createThumbnails()
:
#thumbnailContainer
。sources
資料動態產生縮圖 img
元素。showImage()
。showImage(index)
:
mainImage
的 src
屬性為指定圖片。mainImageCaption
..active
類別。scrollToThumbnail(index)
將對應的縮圖捲動到可視範圍。scrollToThumbnail(index)
: 將對應的縮圖捲動到可視範圍。
startPlayback()
:
isPlaying
為 true
。setInterval()
定時切換圖片,並呼叫 showImage()
。pausePlayback()
:
isPlaying
為 false
。clearInterval()
清除計時器。stopPlayback()
: 完全停止播放 (清除計時器)。
togglePlayback()
: 切換播放/暫停狀態。
handleKeyPress(event)
: 處理鍵盤事件 (空白鍵、左右方向鍵)。
updateInterval()
: 更新間隔時間,並在播放時重新啟動計時器。
showVisibleThumbnails()
:
visibility
屬性。初始化:
initAlbums()
。如何使用:
.html
檔案 (例如 my_album.html
)。photo_galleries
的資料夾。photo_galleries
資料夾中,建立 my_album_1
和 my_album_2
資料夾,並放入對應的圖片。.html
檔案。重要注意事項:
sources
中的 path
正確指向您的圖片資料夾。 此範例使用相對路徑 (例如 ../photo_galleries/my_album_1/
)。 如果您的 HTML 檔案和 photo_galleries
資料夾位於同一層級,則可以使用 ./photo_galleries/my_album_1/
。 如果它們在不同的位置,您需要調整路徑。sources
中的 data
(圖片檔名) 和 description
(描述文字) 與您的實際檔案和內容相符。file:///
,圖片在 http://
開頭的網址),可能會遇到跨域問題。 最簡單的解決方法是將它們放在同一個資料夾中,並使用相對路徑。showVisibleThumbnails()
來優化縮圖的載入,但如果您要處理非常大量的圖片 (數千張),可能需要進一步的優化,例如使用 Web Workers 或更進階的圖片載入技術。const
, let
, 箭頭函式),在較舊的瀏覽器中可能無法正常運作。 如果您需要支援較舊的瀏覽器,您可能需要使用 Babel 或類似的工具將程式碼轉換為更相容的版本。希望這個程式碼對您有幫助!