React项目中模态框无法垂直滚动问题求助
React模态框背景滚动锁定后自身无法滚动的解决方法
问题原因
当你把document.body.style.overflowY设为hidden时,整个页面的滚动被锁定,但模态框本身没有独立的滚动容器,导致内容超出时也无法滚动。
解决步骤
- 修正useEffect依赖:让副作用在
showModal状态变化时触发,确保模态框显示/隐藏时正确切换body的滚动状态。 - 给模态框添加独立滚动容器:将模态框内容放在固定高度的容器内,开启垂直滚动,这样即使body滚动被锁定,模态框内容仍可正常滚动。
修改后的代码
MyModal组件
import { useEffect } from "react"; import "./modal.css"; const MyModal = ({ showModal, setShowModal }) => { useEffect(() => { // 根据模态框显示状态切换body滚动 document.body.style.overflowY = showModal ? "hidden" : "auto"; return () => { // 组件卸载时强制恢复body滚动 document.body.style.overflowY = "auto"; }; }, [showModal]); // 依赖showModal状态,确保状态变化时触发 return ( <div className="modal-background"> <div className="modal-content"> <button onClick={() => { setShowModal(false); }} > Close </button> <p className="heading">This is Modal</p> <p> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. </p> </div> </div> ); }; export default MyModal;
modal.css样式
.modal-background { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; padding: 20px; box-sizing: border-box; } .modal-content { background-color: white; padding: 24px; border-radius: 8px; max-height: 80vh; /* 限制内容容器高度为视口的80% */ overflow-y: auto; /* 内容超出时显示垂直滚动条 */ width: 100%; max-width: 600px; }
原理说明
modal-background设置fixed定位,覆盖整个视口,同时作为遮罩层阻止点击背景内容。modal-content通过max-height限制高度,overflow-y: auto让内容超出时自动开启内部滚动,与body的滚动状态解耦。- 修正后的
useEffect依赖showModal,确保模态框显示/隐藏时同步切换body的滚动状态,避免页面滚动被意外锁定。
内容的提问来源于stack exchange,提问作者Fuaad
相关产品推荐
相关产品推荐

