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

设置body为fixed时透明Header误判页面未滚动的修复方案

问题修复方案

核心原因

设置body为position: fixed后,window.scrollY会被强制重置为0,触发滚动事件里的逻辑,错误地修改Header的类状态。

解决步骤

  • 新增变量标记Modal的打开状态,滚动事件里先判断状态,Modal打开时跳过Header类的修改逻辑
  • 关闭Modal时,根据打开前保存的滚动位置,重新设置Header的类,确保状态和打开前一致
  • 关闭Modal后将页面滚动回之前的位置,优化体验

修改后的完整代码

HTML

<div class="main">
    <div class="header header--is-transparent">HEADER</div>
    <li class="li1"></li>
    <li class="li2"></li>
    <li class="li3"></li>
    <button class="btn">open modal</button>
</div>

CSS

.main {
      height: 2000px;
      width: 100%;
    }

    .header {
      position: fixed;
      top: 0;
      width: 100%;
      height: 50px;
      background-color: rgba(255, 255, 255);
      opacity: 1;
    }

    .header.header--is-transparent {
      opacity: 0.5;
    }

    li {
      height: 300px;
      list-style: none;
    }

    .li1 {
      background: red;
    }

    .li2 {
      background: blue;
    }

    .li3 {
      background: green;
    }

    .btn {
      color: #fff;
      background: #000;
      height: 60px;
      width: 100px;
      position: fixed;
      bottom: 20px;
      left: 20px;
    }

    .modal {
      position: fixed;
      top: 0;
      right: 0;
      height: 100%;
      width: 100%;
      z-index: 999;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .modal-wrapper {
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .modal-content {
      height: 200px;
      width: 200px;
      background: #fff;
      position: absolute;
    }

    .modal-backdrop {
      height: 100%;
      width: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      position: fixed;
      top: 0;
      left: 0;
    }

JavaScript

let scrollY
let isModalOpen = false // 标记Modal是否打开

window.addEventListener('scroll', e => {
  if (isModalOpen) return // Modal打开时不修改Header类
  if (window.scrollY > 100) {
    document.querySelector('.header').classList.remove('header--is-transparent')
  } else {
    document.querySelector('.header').classList.add('header--is-transparent')
  }
})

const btn = document.querySelector('.btn')
btn.addEventListener('click', openModal)

function openModal() {
  scrollY = window.scrollY
  isModalOpen = true

  document.body.style.position = 'fixed'
  document.body.style.overflow = 'hidden'
  document.body.style.width = '100%'
  document.body.style.top = `-${scrollY}px`

  document.querySelector('.main').insertAdjacentHTML('beforeend', `
    <div class="modal">  
      <div class="modal-backdrop"></div>
      <div class="modal-content">
        <h3>Modal content</h3>
        <button class="closeBtn">X</button>
      </div>  
    </div>
  `)
}

function closeModal() {
  document.body.style.position = ''
  document.body.style.overflow = ''
  document.body.style.width = ''
  document.body.style.top = ''
  isModalOpen = false

  // 恢复Header到打开前的状态
  const header = document.querySelector('.header')
  if (scrollY > 100) {
    header.classList.remove('header--is-transparent')
  } else {
    header.classList.add('header--is-transparent')
  }

  document.querySelector('.modal').remove()
  // 回到之前的滚动位置
  window.scrollTo(0, scrollY)
}

document.addEventListener('click', e => {
  if (e.target.closest('.closeBtn')) {
    closeModal()
  }
})

额外说明

  • 通过isModalOpen变量阻断滚动事件对Header的修改,避免Modal打开时的误操作
  • 关闭Modal时基于保存的scrollY重置Header状态,保证前后状态一致
  • 新增window.scrollTo让页面回到打开Modal前的位置,提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:20:25