Angular 2 路由更改时滚动到顶部:为什么重要以及如何实现
\n\n想象一下,您正在浏览一个很长的文档页面,滚动到中间位置,点击一个链接——然后发现自己位于新部分的底部。熟悉吗?正是 Angular 2 路由更改时滚动到顶部 机制解决了这个问题。没有它,用户体验会受到影响:用户必须手动滚动鼠标滚轮或按下 Home 键,这令人烦恼并会增加跳出率。
\n\n在本文中,我们将介绍如何让 Angular 在每次路由切换时自动将页面滚动到顶部。您不仅会学到现成的解决方案,还会理解其工作原理。本文面向初学者,但对希望巩固知识的经验丰富的开发人员也很有用。
\n\n为什么 Angular 不“开箱即用”?
\n\nAngular 是一个强大的 SPA 框架,但其导航行为可能会令人惊讶。默认情况下,路由更改时浏览器 不会重置滚动位置。为什么?因为 Angular Router 将切换视为替换 <router-outlet> 中的组件,而不是加载新页面。浏览器则认为:“我仍在同一个文档上,为什么要滚动?”
如果您有长列表、表格或文档,这一点尤其明显。用户点击页面底部的链接——新内容打开了,但滚动位置仍停留在底部。解决这个问题的方法是明确告诉 Angular:“嘿,每次切换时都滚动到顶部!”
\n\n两种解决方法
\n\n在 Angular 2+ 中实现 路由更改时滚动到顶部 主要有两种方法:
\n\n- \n
- AppComponent 中的全局处理程序——简单,但处理嵌套路由时可能无法正常工作。 \n
- 使用路由配置——更灵活,允许为每个路由单独配置行为。 \n
我们将介绍这两种方法,但我建议使用第二种——它提供了更多控制。
\n\n方法 1:简单的全局处理程序(快速入门)
\n\n打开您的 app.component.ts(或根组件)并添加对 Router 事件的订阅。TypeScript 代码如下:
\nimport { Component, OnInit } from '@angular/core';\nimport { Router, NavigationEnd } from '@angular/router';\nimport { filter } from 'rxjs/operators';\n\n@Component({\n selector: 'app-root',\n templateUrl: './app.component.html',\n styleUrls: ['./app.component.css']\n})\nexport class AppComponent implements OnInit {\n constructor(private router: Router) {}\n\n ngOnInit() {\n this.router.events.pipe(\n filter(event => event instanceof NavigationEnd)\n ).subscribe(() => {\n window.scrollTo(0, 0);\n });\n }\n}\n\n\n这里我们订阅了路由器事件,仅过滤 NavigationEnd(导航完成时),并调用 window.scrollTo(0, 0)。很简单,但有一个问题:如果您有 嵌套路由(例如,组件内的子路由),此代码可能触发过早或根本不触发。
方法 2:使用路由配置的正确解决方案(推荐)
\n\n这种方法使用 Angular Router 中的内置选项 scrollPositionRestoration。从 Angular 6.1 开始,可以直接在路由配置中设置自动恢复/重置滚动。
打开您的 app-routing.module.ts 并在 RouterModule.forRoot() 中添加选项 scrollPositionRestoration: 'top':
\nimport { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\n\nconst routes: Routes = [\n { path: '', component: HomeComponent },\n { path: 'about', component: AboutComponent },\n { path: 'contact', component: ContactComponent }\n];\n\n@NgMod