设置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
相关产品推荐
相关产品推荐

