本教程教你如何在 Bricks 中同步两个可嵌套(nestable)轮播:一个作为主轮播,另一个作为缩略图轮播。
本教程是对 Udoro ‘Cracka’ Essien 最近在群里分享的精彩视频的跟进——他在视频里演示了如何在 Bricks 中同步两个嵌套轮播:一个主轮播,一个用作缩略图。
这篇教程增强了他分享的代码,让你能够:
- 一次设置,永久省心:代码基于 class 而非 ID,加载一次后就不用再碰它
- 同一页面放多个同步轮播组
- 避免与其他插件/代码片段冲突
- 通过防抖(debounce)减少 resize 时的 JS 计算量
开干!
DOM 结构
要让它工作,需要:
- 一个容器(container / section / block / div),class 为
.sync-sliders-wrapper - 两个轮播是这个容器的子元素
- 主轮播需要 class
.sync-sliders-main - 缩略图轮播需要 class
.sync-sliders-thumb
缩略图轮播的 JSON 设置
正如 Cracka 在视频里讲的,你需要把一个自定义 JSON 对象作为缩略图轮播的设置选项粘贴进去。这里直接贴出代码供参考:
{
"type":"slide",
"direction":"ltr",
"keyboard":"global",
"height":"auto",
"gap":10,
"start":0,
"perPage":"3",
"perMove":1,
"speed":400,
"interval":3000,
"autoHeight":true,
"autoplay":false,
"pauseOnHover":false,
"pauseOnFocus":false,
"arrows":false,
"pagination":false,
"focus": "center",
"isNavigation": true,
"updateOnMove": true,
"breakpoints":{
"580":{
"perPage":"2"
}
}
}
其中最重要的字符串是 "isNavigation": true,它会把该轮播设为导航轮播。
注意:截图里光标位置前不应该有逗号。
JavaScript 代码
把下面的代码加载进子主题,或用代码片段插件:
document.addEventListener('DOMContentLoaded', () => {
// Query all the wrappers
const wrappers = document.querySelectorAll('.sync-sliders-wrapper');
// Stop the function if there is no sync slider
if (wrappers.length < 1) return;
// Debounce function
const debounce = (fn, threshold) => {
var timeout;
threshold = threshold || 200;
return function debounced() {
clearTimeout(timeout);
var args = arguments;
var _this = this;
function delayed() {
fn.apply(_this, args);
}
timeout = setTimeout(delayed, threshold);
};
};
// Init function
const init = (mainSliderId, thumbSliderId) => {
const main = bricksData.splideInstances[mainSliderId],
thumbnail = bricksData.splideInstances[thumbSliderId];
// Mount the sync slider
main.sync(thumbnail);
};
// Loop into each wrapper
wrappers.forEach(wrapper => {
// Set the ID of the main slider
const mainSlider = wrapper.querySelector('.sync-sliders-main');
// Check if the main slider class is correctly set
if (!mainSlider) return console.log('No .sync-sliders-main class found');
const mainSliderId = mainSlider.dataset.scriptId;
// Set the ID of the thumb slider
const thumbSlider = wrapper.querySelector('.sync-sliders-thumb');
// Check if the thumb slider class is correctly set
if (!thumbSlider) return console.log('No .sync-sliders-thumb class found');
const thumbSliderId = thumbSlider.dataset.scriptId;
// Run the function on load
setTimeout(() => {
init(mainSliderId, thumbSliderId);
}, 0);
// Rerun the function on resize because bricks reinit the sliders on each resize event
window.addEventListener("resize", debounce(() => {
init(mainSliderId, thumbSliderId);
}, 300));
});
});
这段代码做了什么:
- 页面加载完成后,查询页面上所有
.sync-sliders-wrapper容器; - 从主轮播(
.sync-sliders-main)和缩略图轮播(.sync-sliders-thumb)的data-script-id属性读取 Bricks 轮播实例 ID; - 通过
bricksData.splideInstances拿到对应的 Splide 实例,调用main.sync(thumbnail)建立同步; - 因为 Bricks 在每次 resize 时会重建轮播,所以 resize 事件上用防抖函数(300ms)重新执行绑定。
效果
一切正常的话,前端应该看到:点击缩略图,主轮播跳到对应幻灯片;滑动主轮播时,缩略图的高亮跟着联动。
参考资料
防抖函数
https://www.freecodecamp.org/news/javascript-debounce-example/