React中如何实现点击按钮跳转至另一页面的指定锚点位置?
解决方案
问题根因
window.location.assign 触发页面跳转是异步行为,JS引擎不会等待页面跳转完成再执行后续代码,所以原代码中的scrollTo会先在当前页面执行,等目标页面加载完成后没有对应的滚动逻辑,自然停在页面顶部。
方案1:原生URL哈希锚点方案(无额外依赖,通用所有场景)
利用浏览器原生的锚点定位特性,跳转时在URL后拼接目标元素的id作为哈希值,浏览器加载完目标页面后会自动滚动到对应id的元素位置,代码修改如下:
const goCart = () => { const targetHash = '#Cart-redirect-marker'; if(window.location.pathname !== '/products'){ // 跳转链接拼接锚点哈希 window.location.assign(`${ProductsPageLink()}${targetHash}`); } else { // 已在目标页,直接滚动到指定元素 const targetElement = document.getElementById('Cart-redirect-marker'); targetElement?.scrollIntoView({ behavior: 'smooth' }); } }
如果需要自定义平滑滚动效果,可在全局CSS中添加:
html { scroll-behavior: smooth; }
方案2:React Router 适配方案(项目使用React Router时推荐)
如果你的项目用了React Router v6+,可以用路由提供的能力实现更可控的逻辑:
触发跳转的组件逻辑
import { useNavigate } from 'react-router-dom'; // 组件内部逻辑 const navigate = useNavigate(); const goCart = () => { const targetHash = '#Cart-redirect-marker'; if(window.location.pathname !== '/products'){ navigate('/products', { hash: targetHash }); } else { document.getElementById('Cart-redirect-marker')?.scrollIntoView({ behavior: 'smooth' }); } }
目标页面补充逻辑(可选,适合需要等待内容渲染完成再滚动的场景)
如果目标页面的锚点元素需要等接口请求、数据渲染完成后才存在,可以在Products页面组件内添加监听逻辑:
import { useEffect } from 'react'; // Products页面组件内部 useEffect(() => { if(window.location.hash === '#Cart-redirect-marker') { // 可根据业务调整延迟时间,等待内容渲染完成后再滚动 setTimeout(() => { document.getElementById('Cart-redirect-marker')?.scrollIntoView({ behavior: 'smooth' }); // 不需要保留哈希可执行以下代码清除 // window.history.replaceState(null, '', window.location.pathname); }, 300); } }, []);
内容的提问来源于stack exchange,提问作者Cesar Castillo
相关产品推荐
相关产品推荐

