如何在React Modal组件中实现滚动到顶部功能?
React Modal内滚动到顶部组件修复方案
原代码在普通窗口正常工作,但在React Modal中失效,核心原因是原代码监听的是整个window的滚动,而Modal的滚动区域是其内部独立的容器元素,需要针对Modal的滚动容器做如下修改:
关键修改点
- 不再监听
window的滚动事件,改为监听Modal内部滚动容器的滚动事件 - 滚动到顶部时,调用滚动容器的
scrollTo方法,而非window.scrollTo - 通过
useRef或选择器获取Modal的滚动容器DOM节点
修改后的代码示例
方案一:通过ref传递滚动容器(推荐,适合自定义Modal)
import { useState, useEffect, useRef } from 'react'; import { FaAngleUp } from 'react-icons/fa'; const ScrollToTop = ({ scrollContainerRef }) => { const [showTopBtn, setShowTopBtn] = useState(false); useEffect(() => { const container = scrollContainerRef.current; if (!container) return; const handleScroll = () => { setShowTopBtn(container.scrollTop > 400); }; container.addEventListener("scroll", handleScroll); return () => container.removeEventListener("scroll", handleScroll); }, [scrollContainerRef]); const goToTop = () => { const container = scrollContainerRef.current; if (container) { container.scrollTo({ top: 0, behavior: "smooth", }); } }; return ( <div className="top-to-btm"> {showTopBtn && ( <FaAngleUp className="icon-position icon-style" onClick={goToTop} /> )} </div> ); }; // 在自定义Modal中的使用方式 const CustomModal = () => { const modalScrollRef = useRef(null); return ( <div className="modal-wrapper"> <div className="modal-scroll-content" ref={modalScrollRef}> {/* Modal内部的长内容 */} <ScrollToTop scrollContainerRef={modalScrollRef} /> </div> </div> ); };
方案二:针对第三方Modal库(如react-modal)
如果使用第三方Modal组件,可通过其默认类名获取滚动容器:
import { useState, useEffect } from 'react'; import { FaAngleUp } from 'react-icons/fa'; const ScrollToTop = () => { const [showTopBtn, setShowTopBtn] = useState(false); useEffect(() => { // 以react-modal为例,其滚动容器类名为ReactModal__Content const container = document.querySelector('.ReactModal__Content'); if (!container) return; const handleScroll = () => { setShowTopBtn(container.scrollTop > 400); }; container.addEventListener("scroll", handleScroll); return () => container.removeEventListener("scroll", handleScroll); }, []); const goToTop = () => { const container = document.querySelector('.ReactModal__Content'); if (container) { container.scrollTo({ top: 0, behavior: "smooth", }); } }; return ( <div className="top-to-btm"> {showTopBtn && ( <FaAngleUp className="icon-position icon-style" onClick={goToTop} /> )} </div> ); };
内容的提问来源于stack exchange,提问作者user460567
相关产品推荐
相关产品推荐

