如何实现支持图片与视频自适应时长自动播放的Bootstrap 4轮播
Bootstrap 4 图片+视频自动轮播修复方案
问题说明
需要实现包含图片和视频的自动轮播,要求:
- 共5个幻灯片
- 图片轮播间隔5秒
- 视频按自身时长自动切换,播放时正常运行
原代码存在的核心问题:
- 额外添加的
setInterval会和Bootstrap轮播原生自动切换逻辑冲突 - 多个视频元素使用相同ID(
player2),导致选择器匹配异常 - 初始化视频暂停的逻辑错误,误将
.carousel-item.video容器当成video元素判断 - 视频时长获取时机过早,未等待视频元数据加载完成,导致
duration为NaN - 混用Bootstrap 4和Bootstrap 5的轮播属性(
data-ride和data-bs-ride),引发逻辑混乱
修复后的完整代码
HTML
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/js/bootstrap.min.js" integrity="sha384-3qaqj0lc6sV/qpzrc1N5DC6i1VRn/HyX4qdPaiEFbn54VjQBEU341pvjz7Dv3n6P" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css" integrity="sha384-SI27wrMjH3ZZ89r4o+fGIJtnzkAnFs3E4qz9DIYioCQ5l9Rd/7UAa8DHcaL8jkWt" crossorigin="anonymous"> <title>test</title> </head> <body> <div class="carousel-container"> <div id="myCarousel" class="carousel slide" data-ride="carousel"> <div class="carousel-inner"> <div class="carousel-item active"> <img src="https://img.freepik.com/vector-gratis/fondo-galaxia-dibujos-animados_52683-63638.jpg" class="d-block w-100" alt="..." width="961" height="664"> </div> <div class="carousel-item video"> <video controls class="myvid" id="player1" width="961" height="664"> <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4" type="video/mp4"> </video> </div> <div class="carousel-item video"> <video controls class="myvid" id="player2" width="961" height="664"> <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4" type="video/mp4"> </video> </div> <!-- 可继续添加剩余2个幻灯片 --> </div> <a class="carousel-control-prev" href="#myCarousel" role="button" data-slide="prev"> <span class="carousel-control-prev-icon" aria-hidden="true"></span> <span class="sr-only">上一个</span> </a> <a class="carousel-control-next" href="#myCarousel" role="button" data-slide="next"> <span class="carousel-control-next-icon" aria-hidden="true"></span> <span class="sr-only">下一个</span> </a> </div> </div> </body> </html>
CSS
#myCarousel { max-width: 960px; margin: 0 auto; } .carousel-control-next, .carousel-control-prev { width: 9% !important; } .carousel-inner { background: #FFF; } .carousel-indicators { bottom: -13px !important; } .carousel-item { padding-bottom: 25px; } video { width: 100%; } .carousel-item.active, video { background-color: #FFF } .carousel-container { display: flex; justify-content: center; align-items: center; }
JavaScript
$(document).ready(function() { const carousel = $("#myCarousel"); const defaultInterval = 5000; // 初始化轮播 carousel.carousel({ interval: defaultInterval }); // 初始化所有非当前视频暂停 $('.carousel-item.video').not('.active').find('video').each(function() { this.pause(); this.currentTime = 0; }); // 监听轮播切换事件 carousel.on('slide.bs.carousel', function(ev) { const currentSlide = $(this).find('.carousel-item').eq(ev.from); const nextSlide = $(this).find('.carousel-item').eq(ev.to); // 暂停当前视频并重置进度 const currentVideo = currentSlide.find('video')[0]; if (currentVideo) { currentVideo.pause(); currentVideo.currentTime = 0; } // 处理下一个幻灯片 const nextVideo = nextSlide.find('video')[0]; if (nextVideo) { // 等待视频元数据加载完成后获取时长 nextVideo.addEventListener('loadedmetadata', function() { const videoDuration = this.duration * 1000; // 更新轮播间隔并重启 carousel.carousel('dispose'); carousel.carousel({ interval: videoDuration }); carousel.carousel('cycle'); this.play(); }, { once: true }); // 如果元数据已加载,直接处理 if (nextVideo.readyState >= 2) { const videoDuration = nextVideo.duration * 1000; carousel.carousel('dispose'); carousel.carousel({ interval: videoDuration }); carousel.carousel('cycle'); nextVideo.play(); } } else { // 切换到图片,恢复默认间隔 carousel.carousel('dispose'); carousel.carousel({ interval: defaultInterval }); carousel.carousel('cycle'); } }); });
内容的提问来源于stack exchange,提问作者Uriot
相关产品推荐
相关产品推荐

