lb.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // 获取核心元素
  2. const carousel = document.getElementById('carousel');
  3. const track = document.getElementById('track');
  4. const items = document.querySelectorAll('.carousel-item-db');
  5. // 复制图片列表,实现无缝滚动(关键:轨道末尾拼接原列表)
  6. track.append(...Array.from(items).map(item => item.cloneNode(true)));
  7. // 重新获取包含复制项的所有图片(无缝滚动用)
  8. const allItems = document.querySelectorAll('.carousel-item-db');
  9. // 配置项:可自定义
  10. const config = {
  11. speed: 2, // 滚动速度(越大越快,建议1-5)
  12. centerTolerance: 50, // 居中容差(像素,越小判断越精准,建议30-80)
  13. itemWidth: items[0].offsetWidth + 20 // 单张图片总宽度(含间距)
  14. };
  15. let trackX = 0; // 轨道滚动的X轴偏移量
  16. let isHover = false; // 鼠标是否悬浮,用于暂停滚动
  17. // 1. 核心:更新居中激活状态(实时判断哪个图片在中央)
  18. function updateActiveItem() {
  19. // 容器的水平中心坐标(相对于视口)
  20. const carouselCenter = carousel.getBoundingClientRect().left + carousel.offsetWidth / 2;
  21. allItems.forEach(item => {
  22. // 每张图片的水平中心坐标(相对于视口)
  23. const itemCenter = item.getBoundingClientRect().left + item.offsetWidth / 2;
  24. // 计算图片中心与容器中心的距离
  25. const distance = Math.abs(itemCenter - carouselCenter);
  26. // 距离小于容差 → 判定为居中,添加激活样式;否则移除
  27. if (distance < config.centerTolerance) {
  28. item.classList.add('active-db');
  29. } else {
  30. item.classList.remove('active-db');
  31. }
  32. });
  33. }
  34. // 2. 无级无缝滚动核心逻辑
  35. function animateScroll() {
  36. if (isHover) return; // 鼠标悬浮则暂停滚动
  37. // 轨道向左偏移,实现滚动
  38. trackX -= config.speed;
  39. // 无缝滚动:当轨道滚动距离 ≥ 原列表总宽度时,重置偏移量
  40. if (Math.abs(trackX) >= config.itemWidth * items.length) {
  41. trackX = 0;
  42. }
  43. track.style.transform = `translateX(${trackX}px)`;
  44. // 每次滚动都更新居中激活状态
  45. updateActiveItem();
  46. // 递归执行,实现连续滚动
  47. requestAnimationFrame(animateScroll);
  48. }
  49. // 3. 鼠标悬浮/离开事件:暂停/恢复滚动
  50. carousel.addEventListener('mouseenter', () => {
  51. isHover = true;
  52. });
  53. carousel.addEventListener('mouseleave', () => {
  54. isHover = false;
  55. animateScroll(); // 离开后恢复滚动
  56. });
  57. // 4. 窗口大小变化时,重新计算(适配响应式)
  58. window.addEventListener('resize', updateActiveItem);
  59. // 初始化执行滚动
  60. animateScroll();