仿clay.com功能区:按钮点击与滚动异常技术求助
问题修复方案
核心问题分析
- 按钮点击失效:硬编码滚动位置和GSAP ScrollTrigger的scrub机制冲突,且swiper与ScrollTrigger进度未双向同步,导致点击按钮后swiper切换但滚动进度未跟上,反之亦然。
- 刷新后滚动布局错乱:初始计算swiperWrapperWidth时机过早,DOM未完全渲染导致ScrollTrigger的end值计算错误;未处理窗口resize场景,加上CSS注释语法错误引发样式解析异常。
修复要点
- 移除硬编码scrollPosition,通过GSAP tween进度控制滚动,实现swiper与ScrollTrigger双向同步
- 延迟计算swiperWrapperWidth,确保DOM渲染完成后获取正确宽度
- 修复CSS注释语法错误(将
/ /改为/* */) - 添加窗口resize监听,自动刷新ScrollTrigger
- 优化按钮点击逻辑,通过进度映射定位,摒弃硬编码数值
修复后的完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Clay-style How It Works</title> <style> body { margin: 0; background: #15151e; overflow-x: hidden; } .racesWrapper { position: relative; height: 100vh; /* Adjust based on the number of slides */ overflow: hidden; transition: background-color 1s ease; /* Add this line for smooth color transition */ } .swiper-container { height: 100%; } .swiper-wrapper { display: flex; flex-direction: row; } .swiper-slide { font-family: 'Staatliches', cursive; display: flex; align-items: center; justify-content: center; text-align: center; height: 80vh; width: 100vw; /* Full width for horizontal scroll */ } .button-container { position: absolute; top: 10px; z-index: 1000; display: flex; justify-content: space-around; width: 100%; } .button-container button { display: block; margin-bottom: 5px; width: 24%; height: 50px; cursor: pointer; } .progress-bar { position: absolute; bottom: 0; left: 0; height: 5px; background: #333; width: 100%; z-index: 1000; } .progress-bar-inner { height: 100%; background: #e10600; width: 0; transition: width 0.2s ease, background-color 0.2s ease; } /*Content styling start*/ .swiper-slide .row { width: 100%; height: 100%; margin: 0 auto; } .swiper-slide .col-md-6 { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; padding-inline: 50px; } .swiper-slide .col-md-6 :is(p,h2){ text-align: left; } .swiper-slide .img-wrapper { width: 75%; } .swiper-slide .img-col{ align-items: center !important; justify-content: center !important; } .swiper-slide a.cta-btn { background: #222; color: white; padding: 10px 20px; border-radius: 5px; text-decoration: none; } </style> </head> <body> <div class="racesWrapper"> <!-- Swiper --> <div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"> <div class="row"> <div class="col-md-6"> <h2>Unbeatable Performance 14X Faster Speed</h2> <p>Devrims provides enterprise-grade, managed cloud servers tailored to your specific website and project requirements. The platform offers high performance storage, lightweight technology stacks optimized for PHP applications.</p> <a class="cta-btn" href="#">Start Free Trial</a> </div> <div class="col-md-6 img-col"> <div class="img-wrapper"> <img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" alt="Performance illustration"> </div> </div> </div> </div> <div class="swiper-slide">Flexibility</div> <div class="swiper-slide">Reliability</div> <div class="swiper-slide">Costing</div> </div> </div> <div class="progress-bar"> <div class="progress-bar-inner"></div> </div> <div class="button-container"> <button onclick="goToSlide(0)">Performance</button> <button onclick="goToSlide(1)">Flexibility</button> <button onclick="goToSlide(2)">Reliability</button> <button onclick="goToSlide(3)">Costing</button> </div> </div> <script src="https://unpkg.com/swiper/swiper-bundle.min.js" defer></script> <script src="https://unpkg.com/gsap@3/dist/gsap.min.js" defer></script> <script src="https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js" defer></script> <script> gsap.registerPlugin(ScrollTrigger); let swiper; let horizontalScroll; const colors = [ "#DADDEF", "#D6DAEE", "#D2D5EC", "#CDD3EB", "#CACFE9", "#C6CAE7", "#C1C7E5", "#BDC3E3", "#B9C0E1", "#ADB5DC", "#A9B1DA", "#A5AED8", "#A2ABD6", "#9DA6D4", "#98A3D2", "#919CCF", "#9EA4D3", "#A7AAD5", "#B1AEC8", "#BCB2B6", "#C8B7A3", "#D3BB91", "#DFC07D", "#EAC36A", "#F6C85A", "#FFCC4A", "#F3C264", "#E9B780", "#DDAC9C", "#D2A1B9", "#C697D2", "#BB8BEF", "#B384FE", "#B384FE", "#B384FE", "#B384FE", "#B384FE", "#B384FE" ]; // 等待DOM完全加载后初始化 document.addEventListener('DOMContentLoaded', () => { initSwiper(); initHorizontalScroll(); setupResizeListener(); }); function initSwiper() { swiper = new Swiper('.swiper-container', { direction: 'horizontal', loop: false, speed: 1000, slidesPerView: 1, spaceBetween: 0, // 禁止swiper自身的滑动,交给ScrollTrigger控制 allowTouchMove: false }); swiper.on('slideChange', () => { // 当swiper切换时,同步ScrollTrigger的进度 const progress = swiper.activeIndex / (swiper.slides.length - 1); horizontalScroll.progress(progress); updateProgressBar(progress); }); } function getSwiperWrapperWidth() { return document.querySelector(".swiper-wrapper").scrollWidth; } function initHorizontalScroll() { horizontalScroll = gsap.to(".swiper-wrapper", { xPercent: -100 * (swiper.slides.length - 1), ease: "none", scrollTrigger: { trigger: ".racesWrapper", pin: true, scrub: 1, markers: false, // 调试完可以关掉 start: 'top top', end: () => `+=${getSwiperWrapperWidth()}`, invalidateOnRefresh: true, onUpdate: self => { const progress = self.progress; // 同步swiper的activeIndex const slideIndex = Math.round(progress * (swiper.slides.length - 1)); if (swiper.activeIndex !== slideIndex) { swiper.slideTo(slideIndex, 0); } updateProgressBar(progress); } } }); } function updateProgressBar(progress) { document.querySelector(".progress-bar-inner").style.width = `${progress * 100}%`; const colorIndex = Math.floor(progress * (colors.length - 1)); gsap.to(".racesWrapper", { backgroundColor: colors[colorIndex], duration: 0.3, ease: "power1.inOut" }); } function goToSlide(index) { const progress = index / (swiper.slides.length - 1); // 通过控制GSAP tween的进度来同步滚动和swiper horizontalScroll.progress(progress); swiper.slideTo(index); updateProgressBar(progress); // 刷新ScrollTrigger确保状态正确 ScrollTrigger.refresh(); } function setupResizeListener() { window.addEventListener('resize', () => { // 窗口大小变化时重新计算end值并刷新 horizontalScroll.scrollTrigger.end = `+=${getSwiperWrapperWidth()}`; ScrollTrigger.refresh(); }); } // 初始更新 updateProgressBar(0); </script> </body> </html>
Elementor适配注意事项
- 将代码放入Elementor的自定义HTML模块中
- 确保页面无全局
overflow-x:hidden冲突,必要时给.racesWrapper添加position: relative; z-index: 1; - 若Elementor加载了jQuery,可添加
jQuery.noConflict()避免事件冲突
内容的提问来源于stack exchange,提问作者Ibtisam Bhatti
相关产品推荐
相关产品推荐

