滚动到对应区块时如何同步修改地址栏URL?现有导航高亮代码如何调整
实现方案
你只需要在当前区块ID切换时调用浏览器History API修改地址栏hash即可,不会触发页面刷新,同时先优化原有代码的事件绑定逻辑避免内存泄漏:
- 将scroll事件绑定、DOM查询逻辑移入useEffect,避免重复绑定事件
- 在监听current变化的副作用中新增修改地址栏hash的逻辑
修改后完整代码
import { useState, useEffect } from 'react' // 组件内部逻辑 const [current, setCurrent] = useState('') // 滚动监听逻辑 useEffect(() => { const sections = document.querySelectorAll('h3') const handleScroll = () => { sections.forEach(section => { const sectionId = section.getAttribute('id') if (!sectionId) return const sectionTop = section.offsetTop if (window.pageYOffset >= sectionTop && (window.pageYOffset + 100) - sectionTop < 200 && current !== sectionId) { setCurrent(sectionId) } }) } window.addEventListener('scroll', handleScroll) // 组件卸载时移除事件监听,防止内存泄漏 return () => window.removeEventListener('scroll', handleScroll) }, [current]) // 导航高亮+URL同步逻辑 useEffect(() => { const navLi = document.querySelectorAll('nav ul li') navLi.forEach(li => { li.classList.remove('test') if(li.classList.contains(current)) { li.classList.add('test') } }) // 同步更新地址栏URL if (current) { // replaceState不会新增历史记录,用户点返回不会逐个回滚区块 window.history.replaceState(null, '', `#${current}`) // 如果需要保留滚动历史,支持点后退回到上一个区块,替换为下面这行即可 // window.history.pushState(null, '', `#${current}`) } }, [current])
可选优化
- 页面初始化时如果需要自动定位到URL对应hash的区块,可在组件挂载时读取
window.location.hash,去掉#前缀后赋值给current即可 - 调整代码里的100、200滚动偏移量数值,可匹配实际页面布局,避免hash切换过于频繁
内容的提问来源于stack exchange,提问作者Ivana
相关产品推荐
相关产品推荐

