Basic Carousel
A slide carousel with prev/next arrows, dots and a polite live region.
6 个框架中级
A main image with a clickable thumbnail strip beneath it.
<!--
A thumbnail gallery, not a slide show: the strip is the primary control, so
each thumb is a real button carrying the image's name ("Show Front view") and
aria-current marks the one on display. The selected thumb is marked by a ring
AND by full opacity - never by colour alone.
The big image keeps its alt text; the thumbs are decorative repeats of it, so
their <img> alt is empty and the button label does the talking.
-->
<div class="thumbs" data-thumbs>
<section class="thumbs__main" aria-roledescription="carousel" aria-label="Product gallery">
<div class="thumbs__stage" aria-live="polite">
<img class="thumbs__image" src="/promo/all-access.svg" alt="Front view" data-thumbs-image />
</div>
</section>
<div class="thumbs__strip" role="group" aria-label="Choose an image" data-thumbs-strip>
<button class="thumbs__thumb" type="button" aria-label="Show Front view" aria-current="true" data-src="/promo/all-access.svg" data-alt="Front view">
<img src="/promo/all-access.svg" alt="" />
</button>
<button class="thumbs__thumb" type="button" aria-label="Show Side view" data-src="/promo/all-access.svg" data-alt="Side view">
<img src="/promo/all-access.svg" alt="" />
</button>
<button class="thumbs__thumb" type="button" aria-label="Show Detail view" data-src="/promo/all-access.svg" data-alt="Detail view">
<img src="/promo/all-access.svg" alt="" />
</button>
<button class="thumbs__thumb" type="button" aria-label="Show Packaging" data-src="/promo/all-access.svg" data-alt="Packaging">
<img src="/promo/all-access.svg" alt="" />
</button>
</div>
</div>
<script>
(function () {
document.querySelectorAll('[data-thumbs]').forEach(function (root) {
var image = root.querySelector('[data-thumbs-image]');
var thumbs = Array.prototype.slice.call(root.querySelectorAll('[data-thumbs-strip] button'));
thumbs.forEach(function (thumb) {
thumb.addEventListener('click', function () {
image.src = thumb.dataset.src;
// The alt travels with the image: the live region announces the new
// name, so the user hears WHICH image they landed on.
image.alt = thumb.dataset.alt;
thumbs.forEach(function (other) {
if (other === thumb) other.setAttribute('aria-current', 'true');
else other.removeAttribute('aria-current');
});
});
});
});
})();
</script>| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
items必填 | GalleryImage[] | - | 要渲染的项目数组。 |
onSelect | (index: number) => void | - | 用户选择菜单项时触发,参数为所选项。 |
className | string | - | 合并到根元素上的额外类名。 |
This is a gallery, not a slide show: the strip is the primary control, so every thumb is a real button whose label names the image ("Show Front view") and `aria-current` marks the one on display. Selection shows as a ring *and* full opacity - two signals, never colour alone. The thumbnail `<img>` carries `alt=""` because the button already names it; duplicating the name would make a screen reader say it twice. The big image keeps its real alt, and swapping it by `key` makes the live region see a new node rather than a mutated `src`.