Bootstrap 轮播

🎯 概述

Bootstrap 轮播(Carousel)是一个用于循环展示图片或内容的幻灯片组件。支持自动播放、手动控制、指示器、标题等功能,常用于首页横幅、产品展示等场景。

📦 基本轮播

<div id="carouselExample" class="carousel slide">
    <div class="carousel-inner">
        <div class="carousel-item active">
            <img src="image1.jpg" class="d-block w-100" alt="图片 1">
        </div>
        <div class="carousel-item">
            <img src="image2.jpg" class="d-block w-100" alt="图片 2">
        </div>
        <div class="carousel-item">
            <img src="image3.jpg" class="d-block w-100" alt="图片 3">
        </div>
    </div>
    <button class="carousel-control-prev" type="button" data-bs-target="#carouselExample" data-bs-slide="prev">
        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
        <span class="visually-hidden">上一张</span>
    </button>
    <button class="carousel-control-next" type="button" data-bs-target="#carouselExample" data-bs-slide="next">
        <span class="carousel-control-next-icon" aria-hidden="true"></span>
        <span class="visually-hidden">下一张</span>
    </button>
</div>

🎨 带指示器的轮播

<div id="carouselIndicators" class="carousel slide">
    <!-- 指示器 -->
    <div class="carousel-indicators">
        <button type="button" data-bs-target="#carouselIndicators" data-bs-slide-to="0" class="active"></button>
        <button type="button" data-bs-target="#carouselIndicators" data-bs-slide-to="1"></button>
        <button type="button" data-bs-target="#carouselIndicators" data-bs-slide-to="2"></button>
    </div>
    
    <!-- 轮播内容 -->
    <div class="carousel-inner">
        <div class="carousel-item active">
            <img src="image1.jpg" class="d-block w-100" alt="图片 1">
        </div>
        <div class="carousel-item">
            <img src="image2.jpg" class="d-block w-100" alt="图片 2">
        </div>
        <div class="carousel-item">
            <img src="image3.jpg" class="d-block w-100" alt="图片 3">
        </div>
    </div>
    
    <!-- 控制按钮 -->
    <button class="carousel-control-prev" type="button" data-bs-target="#carouselIndicators" data-bs-slide="prev">
        <span class="carousel-control-prev-icon"></span>
        <span class="visually-hidden">上一张</span>
    </button>
    <button class="carousel-control-next" type="button" data-bs-target="#carouselIndicators" data-bs-slide="next">
        <span class="carousel-control-next-icon"></span>
        <span class="visually-hidden">下一张</span>
    </button>
</div>

📝 带标题的轮播

<div id="carouselCaptions" class="carousel slide">
    <div class="carousel-inner">
        <div class="carousel-item active">
            <img src="image1.jpg" class="d-block w-100" alt="图片 1">
            <div class="carousel-caption d-none d-md-block">
                <h5>第一张幻灯片标题</h5>
                <p>这是第一张幻灯片的描述文字。</p>
            </div>
        </div>
        <div class="carousel-item">
            <img src="image2.jpg" class="d-block w-100" alt="图片 2">
            <div class="carousel-caption d-none d-md-block">
                <h5>第二张幻灯片标题</h5>
                <p>这是第二张幻灯片的描述文字。</p>
            </div>
        </div>
    </div>
</div>

🔄 自动播放

<!-- 添加 data-bs-ride="carousel" 启用自动播放 -->
<div id="carouselAuto" class="carousel slide" data-bs-ride="carousel">
    <div class="carousel-inner">
        <div class="carousel-item active" data-bs-interval="3000">
            <img src="image1.jpg" class="d-block w-100" alt="图片 1">
        </div>
        <div class="carousel-item" data-bs-interval="2000">
            <img src="image2.jpg" class="d-block w-100" alt="图片 2">
        </div>
        <div class="carousel-item">
            <img src="image3.jpg" class="d-block w-100" alt="图片 3">
        </div>
    </div>
</div>

🎭 淡入淡出效果

<div id="carouselFade" class="carousel slide carousel-fade" data-bs-ride="carousel">
    <div class="carousel-inner">
        <div class="carousel-item active">
            <img src="image1.jpg" class="d-block w-100" alt="图片 1">
        </div>
        <div class="carousel-item">
            <img src="image2.jpg" class="d-block w-100" alt="图片 2">
        </div>
    </div>
</div>

🎨 深色变体

<div id="carouselDark" class="carousel carousel-dark slide">
    <div class="carousel-indicators">
        <button type="button" data-bs-target="#carouselDark" data-bs-slide-to="0" class="active"></button>
        <button type="button" data-bs-target="#carouselDark" data-bs-slide-to="1"></button>
    </div>
    <div class="carousel-inner">
        <div class="carousel-item active">
            <img src="light-image1.jpg" class="d-block w-100" alt="图片 1">
            <div class="carousel-caption d-none d-md-block">
                <h5>深色主题标题</h5>
                <p>适用于浅色背景图片。</p>
            </div>
        </div>
    </div>
</div>

💻 JavaScript API

初始化

// 通过 JavaScript 初始化
const carousel = new bootstrap.Carousel('#myCarousel', {
    interval: 2000,
    wrap: true,
    keyboard: true,
    pause: 'hover',
    ride: false,
    touch: true
});

方法

const myCarousel = document.querySelector('#myCarousel');
const carousel = bootstrap.Carousel.getOrCreateInstance(myCarousel);

// 切换到下一张
carousel.next();

// 切换到上一张
carousel.prev();

// 切换到指定索引
carousel.to(2);

// 开始自动播放
carousel.cycle();

// 停止自动播放
carousel.pause();

// 销毁轮播实例
carousel.dispose();

配置选项

const options = {
    interval: 5000,      // 自动播放间隔(毫秒)
    keyboard: true,      // 是否响应键盘事件
    pause: 'hover',      // 鼠标悬停时暂停
    ride: false,         // 是否自动播放
    wrap: true,          // 是否循环播放
    touch: true          // 是否支持触摸滑动
};

const carousel = new bootstrap.Carousel(element, options);

🎭 事件监听

const myCarousel = document.getElementById('myCarousel');

// 幻灯片即将切换时触发
myCarousel.addEventListener('slide.bs.carousel', event => {
    console.log('即将切换到:', event.to);
    console.log('当前索引:', event.from);
    console.log('切换方向:', event.direction);
});

// 幻灯片切换完成后触发
myCarousel.addEventListener('slid.bs.carousel', event => {
    console.log('已切换到:', event.to);
});

🌟 实际示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap 轮播示例</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .carousel-item {
            height: 400px;
            background: #777;
        }
        .carousel-item img {
            object-fit: cover;
            height: 100%;
        }
        .demo-section {
            margin-bottom: 60px;
        }
    </style>
</head>
<body>
    <div class="container my-5">
        <h1>Bootstrap 轮播示例</h1>
        
        <!-- 基本轮播 -->
        <div class="demo-section">
            <h2>基本轮播</h2>
            <div id="basicCarousel" class="carousel slide">
                <div class="carousel-inner">
                    <div class="carousel-item active">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#777"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">第一张</text>
                        </svg>
                    </div>
                    <div class="carousel-item">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#666"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">第二张</text>
                        </svg>
                    </div>
                    <div class="carousel-item">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#555"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">第三张</text>
                        </svg>
                    </div>
                </div>
                <button class="carousel-control-prev" type="button" data-bs-target="#basicCarousel" data-bs-slide="prev">
                    <span class="carousel-control-prev-icon"></span>
                    <span class="visually-hidden">上一张</span>
                </button>
                <button class="carousel-control-next" type="button" data-bs-target="#basicCarousel" data-bs-slide="next">
                    <span class="carousel-control-next-icon"></span>
                    <span class="visually-hidden">下一张</span>
                </button>
            </div>
        </div>
        
        <!-- 带指示器和标题的轮播 -->
        <div class="demo-section">
            <h2>带指示器和标题的轮播</h2>
            <div id="fullCarousel" class="carousel slide" data-bs-ride="carousel">
                <div class="carousel-indicators">
                    <button type="button" data-bs-target="#fullCarousel" data-bs-slide-to="0" class="active"></button>
                    <button type="button" data-bs-target="#fullCarousel" data-bs-slide-to="1"></button>
                    <button type="button" data-bs-target="#fullCarousel" data-bs-slide-to="2"></button>
                </div>
                <div class="carousel-inner">
                    <div class="carousel-item active">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#0d6efd"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">产品展示 1</text>
                        </svg>
                        <div class="carousel-caption d-none d-md-block">
                            <h5>创新产品</h5>
                            <p>我们的最新产品,引领行业潮流。</p>
                        </div>
                    </div>
                    <div class="carousel-item">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#198754"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">产品展示 2</text>
                        </svg>
                        <div class="carousel-caption d-none d-md-block">
                            <h5>优质服务</h5>
                            <p>为客户提供最优质的服务体验。</p>
                        </div>
                    </div>
                    <div class="carousel-item">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#dc3545"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">产品展示 3</text>
                        </svg>
                        <div class="carousel-caption d-none d-md-block">
                            <h5>专业团队</h5>
                            <p>经验丰富的专业团队为您服务。</p>
                        </div>
                    </div>
                </div>
                <button class="carousel-control-prev" type="button" data-bs-target="#fullCarousel" data-bs-slide="prev">
                    <span class="carousel-control-prev-icon"></span>
                    <span class="visually-hidden">上一张</span>
                </button>
                <button class="carousel-control-next" type="button" data-bs-target="#fullCarousel" data-bs-slide="next">
                    <span class="carousel-control-next-icon"></span>
                    <span class="visually-hidden">下一张</span>
                </button>
            </div>
        </div>
        
        <!-- 淡入淡出效果 -->
        <div class="demo-section">
            <h2>淡入淡出效果</h2>
            <div id="fadeCarousel" class="carousel slide carousel-fade" data-bs-ride="carousel">
                <div class="carousel-inner">
                    <div class="carousel-item active" data-bs-interval="2000">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#ffc107"/>
                            <text x="50%" y="50%" fill="#000" font-size="48" text-anchor="middle">淡入淡出 1</text>
                        </svg>
                    </div>
                    <div class="carousel-item" data-bs-interval="2000">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#0dcaf0"/>
                            <text x="50%" y="50%" fill="#000" font-size="48" text-anchor="middle">淡入淡出 2</text>
                        </svg>
                    </div>
                    <div class="carousel-item" data-bs-interval="2000">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#d63384"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">淡入淡出 3</text>
                        </svg>
                    </div>
                </div>
                <button class="carousel-control-prev" type="button" data-bs-target="#fadeCarousel" data-bs-slide="prev">
                    <span class="carousel-control-prev-icon"></span>
                </button>
                <button class="carousel-control-next" type="button" data-bs-target="#fadeCarousel" data-bs-slide="next">
                    <span class="carousel-control-next-icon"></span>
                </button>
            </div>
        </div>
        
        <!-- 控制按钮 -->
        <div class="demo-section">
            <h2>JavaScript 控制</h2>
            <div id="controlCarousel" class="carousel slide mb-3">
                <div class="carousel-inner">
                    <div class="carousel-item active">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#6c757d"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">幻灯片 1</text>
                        </svg>
                    </div>
                    <div class="carousel-item">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#6c757d"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">幻灯片 2</text>
                        </svg>
                    </div>
                    <div class="carousel-item">
                        <svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg">
                            <rect width="800" height="400" fill="#6c757d"/>
                            <text x="50%" y="50%" fill="#fff" font-size="48" text-anchor="middle">幻灯片 3</text>
                        </svg>
                    </div>
                </div>
            </div>
            <div class="btn-group" role="group">
                <button type="button" class="btn btn-primary" id="prevBtn">上一张</button>
                <button type="button" class="btn btn-success" id="playBtn">播放</button>
                <button type="button" class="btn btn-warning" id="pauseBtn">暂停</button>
                <button type="button" class="btn btn-primary" id="nextBtn">下一张</button>
            </div>
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // JavaScript 控制示例
        const controlCarousel = document.getElementById('controlCarousel');
        const carousel = new bootstrap.Carousel(controlCarousel, {
            interval: false,
            wrap: true
        });
        
        document.getElementById('prevBtn').addEventListener('click', () => {
            carousel.prev();
        });
        
        document.getElementById('nextBtn').addEventListener('click', () => {
            carousel.next();
        });
        
        document.getElementById('playBtn').addEventListener('click', () => {
            carousel.cycle();
        });
        
        document.getElementById('pauseBtn').addEventListener('click', () => {
            carousel.pause();
        });
        
        // 监听轮播事件
        controlCarousel.addEventListener('slid.bs.carousel', event => {
            console.log('切换到幻灯片:', event.to + 1);
        });
    </script>
</body>
</html>

✅ 最佳实践

1. 可访问性

<div id="carousel" class="carousel slide" role="region" aria-label="图片轮播">
    <div class="carousel-inner">
        <div class="carousel-item active">
            <img src="image.jpg" class="d-block w-100" alt="详细的图片描述">
        </div>
    </div>
    <button class="carousel-control-prev" type="button" data-bs-target="#carousel" data-bs-slide="prev" aria-label="上一张幻灯片">
        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
        <span class="visually-hidden">上一张</span>
    </button>
</div>

2. 图片优化

<!-- 使用响应式图片 -->
<div class="carousel-item">
    <picture>
        <source media="(min-width: 768px)" srcset="large.jpg">
        <img src="small.jpg" class="d-block w-100" alt="图片">
    </picture>
</div>

3. 性能优化

// 懒加载图片
const carousel = document.getElementById('myCarousel');
carousel.addEventListener('slide.bs.carousel', event => {
    const nextItem = event.relatedTarget;
    const img = nextItem.querySelector('img[data-src]');
    if (img) {
        img.src = img.dataset.src;
        img.removeAttribute('data-src');
    }
});

🎯 常见应用场景

  1. 首页横幅 - 展示主要内容和促销信息
  2. 产品展示 - 多角度展示产品图片
  3. 客户评价 - 轮播显示客户反馈
  4. 新闻动态 - 滚动展示最新新闻
  5. 图片画廊 - 创建图片浏览器

下一步

现在你已经掌握了 Bootstrap 轮播组件的使用方法,接下来我们将学习提示框组件。

下一章:Bootstrap 提示框 →