React页面刷新后滚动缩放Logo的JS函数失效求助
问题解决:React中滚动缩小Logo功能刷新后失效
问题根源
你直接在组件外部绑定window.onscroll事件,没有和React组件的生命周期同步。刷新页面时,组件可能还未完成DOM渲染,document.getElementById("navbar-logo")会找不到元素导致功能失效;另外这种全局绑定方式不会在组件卸载时清理事件监听,容易引发内存泄漏。
解决方案:用React钩子规范实现
通过useRef安全获取DOM元素,结合useEffect在组件挂载时添加滚动监听,卸载时移除监听,确保操作和组件生命周期同步。
优化后的代码示例
import React, { useEffect, useRef } from 'react'; import { Navbar, Container, Nav } from 'react-bootstrap'; import Logo from './path-to-your-logo'; // 替换为你的Logo实际路径 const Navigation = () => { // 创建ref绑定到Logo元素 const logoRef = useRef(null); useEffect(() => { // 滚动处理函数 const handleScroll = () => { // 确保元素已挂载后再操作 if (!logoRef.current) return; if (window.scrollY > 50) { logoRef.current.style.cssText = "width: 22%; position: relative; top: -38px; left: 150px;"; } else { logoRef.current.style.cssText = "width: 28%;"; } }; // 添加滚动监听 window.addEventListener('scroll', handleScroll); // 组件卸载时清理监听,避免内存泄漏 return () => window.removeEventListener('scroll', handleScroll); }, []); // 空依赖数组确保只在组件挂载/卸载时执行一次 return ( <div className="body"> <div className='container'> <Navbar collapseOnSelect expand="lg" variant="dark" fixed="top" className="navbarBg navbar-fixed-top"> <Container className="logo-className"> <Navbar.Toggle aria-controls="basic-navbar-nav" /> <Navbar.Collapse id="basic-navbar-nav"> <Nav className="me-auto links"> <Nav.Link className="nav-items text-nowrap active left" href="#header-container">Home</Nav.Link> <Nav.Link className="nav-items text-nowrap left" href="#about-section">About Us</Nav.Link> <Nav.Link className="nav-items text-nowrap left" href="#sevices-container">Services</Nav.Link> <Nav.Link className="text-nowrap mobile"> {/* 将ref绑定到img元素 */} <img ref={logoRef} id='navbar-logo' src={Logo} alt='logo' loading="lazy" /> </Nav.Link> <Nav.Link className="nav-items text-nowrap right" href="#Our-games">Our Projects</Nav.Link> <Nav.Link className="nav-items text-nowrap right" href="#">Blog</Nav.Link> <Nav.Link className="nav-items text-nowrap right" href="#contact">Contact Us</Nav.Link> </Nav> </Navbar.Collapse> </Container> </Navbar> </div> </div> ); }; export default Navigation;
更推荐的样式管理方式
直接操作style不够优雅,建议用CSS类控制样式,实现样式与逻辑分离:
- 在CSS文件中定义类:
#navbar-logo { width: 28%; transition: all 0.3s ease; /* 添加过渡动画,提升交互流畅度 */ } #navbar-logo.scrolled { width: 22%; position: relative; top: -38px; left: 150px; }
- 修改滚动处理函数:
const handleScroll = () => { if (!logoRef.current) return; if (window.scrollY > 50) { logoRef.current.classList.add('scrolled'); } else { logoRef.current.classList.remove('scrolled'); } };
核心改进点
- useRef:替代
document.getElementById,确保组件能安全访问到对应的DOM元素,避免元素未挂载时的错误 - useEffect:通过生命周期钩子管理事件监听,保证组件挂载后才绑定事件,卸载时清理监听,避免内存泄漏
- 安全判断:加入
!logoRef.current的判断,防止元素未加载时执行操作报错
内容的提问来源于stack exchange,提问作者taha akram
相关产品推荐
相关产品推荐

