Angular启用scrollPositionRestoration后锚点跳转失效,如何按需启用?
解决scrollPositionRestoration与同页面锚点跳转的冲突问题
方案一:自定义scrollPositionRestoration函数(推荐)
直接在路由配置中通过自定义函数判断场景,分别处理页面切换和同页面锚点跳转:
- 导入所需类型:
import { ActivatedRouteSnapshot, NavigationState } from '@angular/router';
- 修改路由配置,替换原有的
scrollPositionRestoration设置:
imports: [ RouterModule.forRoot(routes, { scrollPositionRestoration: (route: ActivatedRouteSnapshot, navigationState: NavigationState) => { // 获取上一次导航的完整URL、当前路由路径和锚点 const previousFullUrl = navigationState?.previousNavigation?.finalUrl?.toString(); const currentPath = `/${route.url.join('/')}`; const currentFragment = route.fragment; // 判断是否为同页面锚点跳转:路径一致且存在锚点参数 if (previousFullUrl && currentFragment) { const previousPath = previousFullUrl.split('#')[0]; if (previousPath === currentPath) { // 手动触发锚点滚动,返回null跳过Angular默认滚动行为 setTimeout(() => { const targetElement = document.getElementById(currentFragment); if (targetElement) { targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); return null; } } // 非锚点跳转场景,启用默认的滚动位置恢复功能 return 'enabled'; } }) ]
方案二:通过Router事件监听处理
在根组件中监听导航结束事件,针对性处理同页面锚点跳转:
- 在
AppComponent中注入Router并监听NavigationEnd事件:
import { Component, OnInit } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor(private router: Router) {} ngOnInit(): void { this.router.events.subscribe(event => { if (event instanceof NavigationEnd) { const currentUrl = this.router.parseUrl(event.url); const fragment = currentUrl.fragment; const previousNavigation = this.router.getCurrentNavigation()?.previousNavigation; // 校验是否为同页面锚点跳转 if (previousNavigation && fragment) { const previousPath = previousNavigation.finalUrl?.split('#')[0]; const currentPath = currentUrl.split('#')[0]; if (previousPath === currentPath) { // 延迟执行确保DOM已更新,再滚动到目标锚点 setTimeout(() => { const target = document.getElementById(fragment); if (target) { target.scrollIntoView({ behavior: 'smooth' }); } }); } } } }); } }
两种方案均可实现:页面切换时保留scrollPositionRestoration的滚动位置恢复功能,同页面点击带fragment的routerLink时,正常滚动到指定锚点位置。
内容的提问来源于stack exchange,提问作者Igor Cantele
相关产品推荐
相关产品推荐

