使用JavaScript与CSS实现视差效果时滚动联动代码不生效如何解决
问题根源
你的代码没有效果是几个低级错误叠加导致的:
- 页面没有可滚动空间:你只写了一个高度为
100vh的section标签,body没有设置额外高度,整个页面高度刚好等于浏览器视口高度,window.scrollY的值永远是0,你修改left属性的代码虽然执行了,但赋值永远是0px,自然看不到任何变化。 - CSS存在无效属性:你给body写的
size: 100%是不存在的CSS属性,不会生效。 - 偏移逻辑和样式冲突:你给所有section下的img统一设置了
left: 0、width: 100%,就算页面能滚动,直接给left赋正的scrollY值只会让元素向右偏移,同时因为元素宽度是100%,偏移后右侧会出现空白,也不会有你预期的视差错位感。 - 没有做层级区分:所有图片z-index默认是auto,上层图片会完全盖住下层,就算下层元素位移了也看不到。
- 没有隐藏横向溢出:元素横向偏移时会出现横向滚动条,破坏效果。
修复步骤
- 先给页面增加滚动空间,比如给body设置
min-height: 200vh,让页面高度是视口的2倍,产生足够的滚动距离。 - 修正CSS错误:删掉无效的
size属性,给html、body设置overflow-x: hidden隐藏横向滚动条。 - 优化位移实现:不要直接修改
left属性(会触发页面重排,性能差),改用transform: translateX()做位移,性能更好;如果要元素向左移动,偏移值要给负值,同时给不同层的图片设置不同的位移系数,才能做出层次感的视差效果,而不是两层移动速度完全一样。 - 给不同图片设置明确的z-index,区分前后层级,避免被完全遮挡。
修正后可运行代码
CSS部分
* { scroll-behavior: smooth; margin: 0; padding: 0; box-sizing: border-box; } html, body { width: 100%; min-height: 200vh; /* 给页面加足够的滚动高度 */ overflow-x: hidden; /* 隐藏横向滚动条 */ } section { position: relative; width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; } section::before { content: ''; position: absolute; bottom: 0; width: 100%; height: 100px; background-image: linear-gradient(to bottom right, #350529, #45392c); z-index: 100; } section img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; } /* 分层设置z-index,越靠前的景层级越高 */ #first { z-index: 1; } #second { z-index: 2; } #third { z-index: 3; } #fourth { z-index: 4; } #fifth { z-index: 5; } #text { z-index: 9; } section img#sixth { z-index: 10; } #text { position: absolute; color: white; white-space: nowrap; font-size: 7.5vw; }
JS+HTML部分
<section> <img src="Plan-parallax-1.png" id="first"> <img src="Plan-parallax-2.png" id="second"> <img src="Plan-parallax-3.png" id="third"> <img src="Plan-parallax-4.png" id="fourth"> <img src="Plan-parallax-5.png" id="fifth"> <h2 id="text">Monde parallele</h2> <img src="Plan-parallax-6.png" id="sixth"> </section> <script> window.addEventListener('scroll', function(){ const scrollY = window.scrollY; // 不同层设置不同的位移系数,越远的景移动越慢,才有视差感 document.getElementById("second").style.transform = `translateX(${-scrollY * 0.5}px)`; document.getElementById("third").style.transform = `translateX(${-scrollY * 0.7}px)`; // 可以给其他层也加上不同速度的位移,效果更好 document.getElementById("text").style.transform = `translateY(${scrollY * 0.8}px)`; }) </script>
额外优化建议
- scroll事件触发频率很高,如果追求更流畅的效果,可以给滚动逻辑加节流,或者用
requestAnimationFrame优化。 - 如果要做常规的垂直视差,把
translateX改成translateY即可,逻辑完全一致。 - 注意图片本身的尺寸,如果是做横向位移的视差,图片宽度要比视口宽,不然位移到边缘会露出空白。
内容的提问来源于stack exchange,提问作者hey
相关产品推荐
相关产品推荐

