1. Overview
Challenge & starter files: Advent of JS
Full codes: nilstarbb/advent-of-js/9-image-carousel
Live Demo: 09 - Image Carousel || Advent of JavaScript
Preview:
2. Details
Users should be able to:
- toggle left and right through the image thumbnails
- click an image to select it manually
3. Coding
Setup React template
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
...
<link rel="stylesheet" href="./styles.css" />
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div class="wrapper menu" id="wrapper"></div>
<script type="text/babel" src="./script.js"></script>
</body>
</html>
script.js:
const { useState, useEffect } = React;
const App = () => {
return (
<>
...
</>
);
};
ReactDOM.render(<App />, document.getElementById("wrapper"));
Build the carousel
Carousel 的逻辑如下:
- 数组 content 储存图片信息,selected 记录当前主图序号。
- 初始化显示第一张图片 content[0] 为主图。
- 点击下方缩略图后,用该图片替换主图,更新 selected。
- 点击左/右箭头,替换主图为前/后一张图片,
selected--/selected++
。 - 限定 selected 的取值范围:
selected >= 0 && selected < content.length
。
const App = () => {
const [selected, setSelected] = useState(0);
const changeSelected = (key) => {
if (key >= 0 && key < content.length) {
setSelected(key);
}
};
return (
<>
<div className="feature">
<img
src={"./images/" + content[selected].image}
alt={content[selected].caption}
/>
<div className="caption">{content[selected].caption}</div>
</div>
<div className="thumbnails">
<ul>
{content.map((img, index) => (
<li
key={index}
className={selected == index ? "selected" : ""}
onClick={() => changeSelected(index)}
>
<a href="#">
<img src={"./images/" + img.image} alt={img.caption} />
</a>
</li>
))}
</ul>
</div>
<a href="#" className="left" onClick={() => changeSelected(selected - 1)}>
<img src="./images/chevron.svg" alt="" />
</a>
<a
href="#"
className="right"
onClick={() => changeSelected(selected + 1)}
>
<img src="./images/chevron.svg" alt="" />
</a>
</>
);
};