在Bootstrap多滑块轮播中nextElementSibling的作用是什么?
关于el.nextElementSibling的行为澄清
el.nextElementSibling是标准DOM API,只会返回当前元素同层级的下一个相邻元素节点,如果没有下一个相邻元素就返回null,绝对不会同时选中多个元素。你观察到的“同时选中所有带carousel-item类的DIV”是这段JS的循环遍历+克隆逻辑叠加产生的效果,和该API本身的行为无关。
Bootstrap多卡片轮播实现原理
这个改造后的轮播实现了一次显示4张卡片、每次切换只滚动1张卡片的效果,核心逻辑是通过预克隆卡片到单个轮播项内,复用原生Bootstrap轮播的切换能力,没有修改Bootstrap底层逻辑。
核心逻辑拆解
JS代码逻辑
let items = document.querySelectorAll('.carousel .carousel-item') items.forEach((el) => { const minPerSlide = 4 let next = el.nextElementSibling for (var i=1; i<minPerSlide; i++) { if (!next) { console.log("no next") // 没有下一个元素时回到第一个轮播项,实现首尾循环 next = items[0] } let cloneChild = next.cloneNode(true) el.appendChild(cloneChild.children[0]) next = next.nextElementSibling } })
逻辑步骤:
- 先获取所有原始轮播项DOM节点,示例里一共有6个
carousel-item,每个原始轮播项里只有1张卡片。 - 遍历每一个原始轮播项,给每个轮播项补够4张卡片:
- 首先设定每个轮播帧要显示的卡片数量为4
- 先获取当前轮播项的下一个相邻轮播项
- 循环3次(当前轮播项本身已经有1张卡片,还需要补3张):
- 如果已经遍历到最后一个轮播项的下一位没有元素,就跳回第一个轮播项,实现轮播首尾衔接的效果
- 把下一个轮播项里的卡片克隆一份,追加到当前轮播项内部
- 再获取下一个相邻轮播项,继续补卡片
- 处理完成后每个
carousel-item内部都有4张卡片,配合CSS(示例里用的col-md-3,4个刚好占满1行),就实现了单个轮播帧显示4张卡片的效果,切换的时候原生Bootstrap轮播一次滑过1个carousel-item,视觉上就是每次只滚动1张卡片,剩下3张留在视野内。
配套HTML结构
<div class="container text-center my-3"> <h2 class="font-weight-light">Bootstrap Multi Slide Carousel</h2> <div class="row mx-auto my-auto justify-content-center"> <div id="recipeCarousel" class="carousel slide" data-bs-ride="carousel"> <div class="carousel-inner" role="listbox"> <div class="carousel-item active"> <div class="col-md-3"> <div class="card"> <div class="card-img"> <img src="//via.placeholder.com/500x400/31f?text=1" class="img-fluid"> </div> <div class="card-img-overlay">Slide 1</div> </div> </div> </div> <div class="carousel-item"> <div class="col-md-3"> <div class="card"> <div class="card-img"> <img src="//via.placeholder.com/500x400/e66?text=2" class="img-fluid"> </div> <div class="card-img-overlay">Slide 2</div> </div> </div> </div> <div class="carousel-item"> <div class="col-md-3"> <div class="card"> <div class="card-img"> <img src="//via.placeholder.com/500x400/7d2?text=3" class="img-fluid"> </div> <div class="card-img-overlay">Slide 3</div> </div> </div> </div> <div class="carousel-item"> <div class="col-md-3"> <div class="card"> <div class="card-img"> <img src="//via.placeholder.com/500x400?text=4" class="img-fluid"> </div> <div class="card-img-overlay">Slide 4</div> </div> </div> </div> <div class="carousel-item"> <div class="col-md-3"> <div class="card"> <div class="card-img"> <img src="//via.placeholder.com/500x400/aba?text=5" class="img-fluid"> </div> <div class="card-img-overlay">Slide 5</div> </div> </div> </div> <div class="carousel-item"> <div class="col-md-3"> <div class="card"> <div class="card-img"> <img src="//via.placeholder.com/500x400/fc0?text=6" class="img-fluid"> </div> <div class="card-img-overlay">Slide 6</div> </div> </div> </div> </div> <a class="carousel-control-prev bg-transparent w-aut" href="#recipeCarousel" role="button" data-bs-slide="prev"> <span class="carousel-control-prev-icon" aria-hidden="true"></span> </a> <a class="carousel-control-next bg-transparent w-aut" href="#recipeCarousel" role="button" data-bs-slide="next"> <span class="carousel-control-next-icon" aria-hidden="true"></span> </a> </div> </div> <h5 class="mt-2 fw-light">每次切换滚动1张卡片</h5> </div>
效果示意图

内容的提问来源于stack exchange,提问作者Ross Symonds
相关产品推荐
相关产品推荐

