挑戰:圖片庫
在本挑戰中,我們將指導您構建一個在許多網站上都能看到的常見專案 — 一個由 JavaScript 驅動的圖片庫。在此過程中,您將測試您對迴圈、函式、條件語句、事件、DOM 指令碼和物件基礎知識的掌握程度。
起始點
首先,點選下方程式碼面板中的播放按鈕,在MDN Playground中開啟提供的示例。然後,你將按照專案簡介部分中的說明完成JavaScript功能。
HTML 如下所示:
<h1>Image gallery example</h1>
<div class="full-img">
<img
class="displayed-img"
src="https://mdn.github.io/shared-assets/images/examples/learn/gallery/pic1.jpg"
alt="Closeup of a human eye" />
<div class="overlay"></div>
<button class="dark">Darken</button>
</div>
<div class="thumb-bar"></div>
起始的 JavaScript 程式碼如下:
const displayedImage = document.querySelector(".displayed-img");
const thumbBar = document.querySelector(".thumb-bar");
const btn = document.querySelector("button");
const overlay = document.querySelector(".overlay");
為簡潔起見,我們隱藏了圖片庫的 CSS,但您可以在 MDN Playground 中檢視此應用時看到它。
專案簡介
我們為您提供了一些 HTML、CSS 和幾行 JavaScript 程式碼。您的任務是遵循以下說明,編寫必要的 JavaScript,將其轉換為一個可用的圖片庫。
圖片庫將由一張大圖和一排縮圖組成。當點選或透過 Tab 鍵聚焦縮圖並按下 Enter/Return 鍵時,該縮圖應顯示為大圖。相應的 <img> 元素也應更新為正確的 alt 文字。
左上角有一個按鈕,反覆按下該按鈕可以切換大圖在較暗和較亮色調之間的顯示效果,這是透過更改覆蓋在大圖上方的 <div> 元素的透明度來實現的。
您需要在示例中嵌入的圖片及其所需的 alt 文字如下:
建立一個數據物件
首先,我們希望您宣告一個名為 images 的物件陣列。每個物件應包含兩個屬性:
filename:圖片檔案的名稱(不是完整 URL)。alt:圖片的alt文字。
將圖片新增到縮圖欄
接下來,我們希望您迴圈遍歷 images 陣列,並使用一些 DOM 指令碼透過 <img> 元素將它們全部嵌入到頁面中。它們應作為類名為 thumb-bar 的 <div> 元素的子元素包含,我們已經在 thumbBar 常量中引用了它。
- 建立一個名為
baseURL的常量,其中包含每個圖片檔案的基本 URL(URL 中不包含檔名部分)。 - 建立一個
for ... of迴圈來遍歷images陣列。 - 對於每個圖片,建立一個新的
<img>元素。 - 將
<img>的源設定為圖片的 URL,該 URL 應該是baseURL和filename的組合;並將alt屬性設定為alt文字。 - 為
<img>新增另一個屬性,使其可以透過鍵盤焦點訪問。 - 將
<img>元素追加到thumbBar。 - 為
<img>新增一個click事件處理程式,以便在單擊它時,會執行一個名為updateDisplayedImage()的函式,該函式會將單擊的圖片以全尺寸顯示。您將在稍後建立此函式。 - 為
<img>新增另一個事件處理程式,以便一旦透過鍵盤聚焦,就可以透過按 Enter/Return 鍵(僅此鍵)來以全尺寸顯示單擊的圖片。這是一個有挑戰性的目標,需要一些研究才能弄清楚。
建立 updateDisplayedImage() 函式
現在是時候建立用於以全尺寸顯示啟用縮圖的函數了。我們已將全尺寸 <img> 元素的引用儲存在 displayedImage 常量中。
- 定義
updateDisplayedImage()函式。 - 在函式體內,將
displayedImage的源設定為已啟用的<img>元素的源。 - 將
displayedImage的 alt 文字設定為已啟用的<img>元素的 alt 文字。
連線“變暗/變亮”按鈕
我們已將“變暗/變亮” <button> 的引用儲存在 btn 常量中,並將覆蓋在全尺寸 <img> 上方的透明 <div> 的引用儲存在 overlay 常量中。我們希望您:
- 為
<button>新增一個click事件處理程式,並將一個匿名函式設定為處理程式函式。 - 在函式體內,新增一個條件結構,測試
<button>是否具有dark類。 - 如果
<button>被點選時具有dark類,將其文字內容更改為Lighten,並將overlay元素的背景顏色更改為rgb(0 0 0 / 0.5)。移除<button>元素的dark類。 - 如果
<button>被點選時不具有dark類,將其文字內容更改為Darken,並將overlay元素的背景顏色更改為rgb(0 0 0 / 0)。新增<button>元素的dark類。 - 您能否想出一個方法,使用一行程式碼來切換
dark類,並在條件結構之後執行?這也是一個有挑戰性的目標,但值得嘗試。
提示和技巧
- 您無需更改 HTML 或 CSS。
示例
你完成的應用程式應該像以下即時示例一樣工作:
點選此處顯示解決方案
完成的JavaScript應該如下所示:
const displayedImage = document.querySelector(".displayed-img");
const thumbBar = document.querySelector(".thumb-bar");
const btn = document.querySelector("button");
const overlay = document.querySelector(".overlay");
// Solution: Create a data object
const images = [
{ filename: "pic1.jpg", alt: "Closeup of a human eye" },
{ filename: "pic2.jpg", alt: "Rock that looks like a wave" },
{ filename: "pic3.jpg", alt: "Purple and white pansies" },
{ filename: "pic4.jpg", alt: "Section of wall from a pharaoh's tomb" },
{ filename: "pic5.jpg", alt: "Large moth on a leaf" },
];
// Solution: Loop through the images
// Create a baseURL constant containing the baseURL of the images
const baseURL =
"https://mdn.github.io/shared-assets/images/examples/learn/gallery/";
// Loop through the images using a for...of loop
for (const image of images) {
// Create a new image element
const newImage = document.createElement("img");
// Set the source and alt text for the image
newImage.src = `${baseURL}${image.filename}`;
newImage.alt = image.alt;
// Make the image focusable via the keyboard
newImage.tabIndex = "0";
// Append the image as a child of the thumbBar
thumbBar.appendChild(newImage);
// Update the display to show the image full size when a thumb is clicked
newImage.addEventListener("click", updateDisplayedImage);
// Update the display to show the image full size when the "Enter" key
// is pressed after it has been focused
newImage.addEventListener("keydown", (e) => {
if (e.code === "Enter") {
updateDisplayedImage(e);
}
});
}
// Solution: Create the updateDisplayedImage() function
function updateDisplayedImage(e) {
displayedImage.src = e.target.src;
displayedImage.alt = e.target.alt;
}
// Solution: Wire up the Darken/Lighten button
// Add a click event listener on the button
btn.addEventListener("click", () => {
// If the button has a "dark" class set,
// change text to "Lighten" and make the overlay darker
if (btn.classList.contains("dark")) {
btn.textContent = "Lighten";
overlay.style.backgroundColor = "rgb(0 0 0 / 0.5)";
} else {
// Else, change text to "Darken" and make
// the overlay lighter
btn.textContent = "Darken";
overlay.style.backgroundColor = "rgb(0 0 0 / 0)";
}
// Toggle the class ready for the next button press
btn.classList.toggle("dark");
});