You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

滚动切换div显隐时如何让bg-2与bg-1位置一致无截断

问题原因

你这代码出偏移、截断的问题核心是三个低级错误:

  • 用hide()/show()本质是切display:none,被隐藏的元素直接脱离文档流,两个bg块的offsetTop会随着你切显隐来回跳,拿这个动态变的值当滚动判断阈值,逻辑肯定乱,位置自然对不齐
  • 最顶部那个空的fixed块宽度写错了,width:100vh是拿视口高度当宽度,本身写法就错,还干扰偏移计算
  • 写在滚动事件里的lastScrollTop每次触发都重新赋值为0,根本记不住上一次的滚动位置,判断逻辑完全是乱的。
修复方法

别用display切显隐,把两个bg块叠在同一个固定高度的容器里,切换的时候只改层级,全程不触发文档流重排,位置就不会飘:

  • 给两个bg块套一个共同的父容器,高度设成你要的80vh,父容器开相对定位
  • 两个bg块都开绝对定位撑满整个父容器,完全重叠,默认只让bg1显示在最上层
  • 滚动判断的阈值提前算好固定值,别在滚动事件里反复拿会变的子元素offsetTop算
  • 那个写错尺寸的空fixed块直接删掉就行,没用。
修正后完整代码
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>滚动切换Demo</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <style>
      .bg-wrap {
        position: relative;
        height: 80vh;
      }
      .bg-1 {
        position: absolute;
        inset: 0;
        background: blue;
        z-index: 10;
      }
      .bg-2 {
        position: absolute;
        inset: 0;
        background: red;
        z-index: 1;
      }
      .bg-3 {
        height: 150vh;
        background: pink;
      }
      .active {
        z-index: 999;
      }
    </style>
  </head>
  <body>
    <div class="bg-wrap" id="bgWrap">
      <div class="bg-1 active" id="bg-1">
        This is testing UI
      </div>
      <div class="bg-2" id="bg-2">
        This is another testing UI
      </div>
    </div>
    <div class="bg-3">
      This is third testing UI
    </div>

    <script>
      const bgWrap = document.getElementById('bgWrap')
      const bg1 = document.getElementById('bg-1')
      const bg2 = document.getElementById('bg-2')
      // 提前计算固定切换阈值,避免滚动时反复计算动态偏移值
      const triggerPoint = bgWrap.offsetTop + bgWrap.offsetHeight - window.innerHeight
      let lastScrollY = window.scrollY

      window.addEventListener("scroll", function () {
        const currentScroll = window.scrollY
        // 滚动到距离bg容器底部100px位置时切换到bg2,回滚时切回bg1
        if (currentScroll > triggerPoint - 100) {
          bg2.classList.add('active')
          bg1.classList.remove('active')
        } else {
          bg1.classList.add('active')
          bg2.classList.remove('active')
        }
        lastScrollY = currentScroll
      });
    </script>
  </body>
</html>
效果说明
  • 两个bg层完全重叠在同一个父容器里,切换的时候只改层级,不会脱离文档流,完全不会出现位置偏移、内容截断的问题
  • 切换阈值提前计算为固定值,不会因为元素显隐发生跳变,滚动触发逻辑稳定
  • 如果需要做滚动方向判断(比如上滚切bg1、下滚切bg2),只要对比currentScroll和lastScrollY的大小即可,逻辑不会混乱。

内容的提问来源于stack exchange,提问作者TechDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 15:36:18