Angular: прокрутите страницу до раздела загрузки страницы при переходе к определенному фрагменту URL-адреса

Я работаю над приложением Angular, и у меня есть функция, которая плавно прокручивает до определенного раздела страницы. Функция работает отлично, когда я запускаю ее вручную. Однако я хочу, чтобы страница автоматически прокручивалась до определенного раздела, когда пользователь переходит непосредственно к URL-адресу с фрагментом, например http://localhost:4200/section-2.

Как я могу изменить свой код или реализовать дополнительную логику, чтобы гарантировать, что при загрузке страницы с определенным фрагментом URL-адреса она автоматически прокручивается до этого раздела?

Вот моя текущая функция прокрутки:

public scrollToSection(sectionId: string): void {
  const targetElement = document.getElementById(sectionId);
  if (targetElement) {
    const navHeight = this.navigationService.getNavHeight();
    const yPosition = targetElement.getBoundingClientRect().top + window.scrollY - navHeight;
    window.scrollTo({ top: yPosition, behavior: 'smooth' });
  }
}

🤔 А знаете ли вы, что...
С JavaScript можно создавать интерактивные формы и проверять введенные пользователем данные.


50
2

Ответы:

Примечание. Люди могут оказаться более полезными, если вы напишете свои вопросы более четко.

Я не уверен, правильно ли я это понял, но вы можете использовать эти методы; Коды не проверял, но должно работать.

Угловой;

Если вы определили часть «section-2» как параметр «:elementid» при определении маршрутов;

Вариант 1: (Это статическое значение. Когда оно меняется, его может быть сложно отслеживать.)

let elementId = this.activatedRoute.snapshot.params['elementid'];
this.scrollToSection(elementId)

Вариант 2: (Это можно отследить.)

this.activatedRoute.params.pipe(
 map(params => params.elementid),
 switchMap(elementId=> this.scrollToSection(elementId)
);

Чистый JS в Angular;

(Есть и другие методы.)

let id = window.location.pathname.substring(1);
this.scrollToSection(id);

(Обычно рекомендуется использовать метод angular вместо js в Angular.)


Решено
  1. У вас должен быть компонент для переноса всех разделов. В этом компоненте извлеките первый путь маршрута и прокрутите до раздела.

home.comComponent.ts

import { Component } from '@angular/core';
import { Section1Component } from '../section1/section1.component';
import { Section2Component } from '../section2/section2.component';
import { Section3Component } from '../section3/section3.component';
import { Section4Component } from '../section4/section4.component';
import { CommonModule } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
import { NavigationService } from '../navigation.service';

@Component({
  selector: 'app-home',
  standalone: true,
  imports: [
    Section1Component,
    Section2Component,
    Section3Component,
    Section4Component,
    CommonModule,
  ],
  template: `
    <app-section1></app-section1>
    <app-section2></app-section2>
    <app-section3></app-section3>
    <app-section4></app-section4>
  `,
})
export class HomeComponent {
  name = 'Angular';

  constructor(
    private activatedRoute: ActivatedRoute,
    private navigationService: NavigationService
  ) {}

  ngOnInit(): void {
    this.activatedRoute.pathFromRoot &&
      this.activatedRoute.pathFromRoot.length > 0 &&
      this.activatedRoute.pathFromRoot[1].url.subscribe((url) => {
        let elementId = url[0].path;

        this.scrollToSection(elementId);
      });
  }

  public scrollToSection(sectionId: string): void {
    const targetElement = document.getElementById(sectionId);
    if (targetElement) {
      const navHeight = this.navigationService.getNavHeight();
      const yPosition =
        targetElement.getBoundingClientRect().top + window.scrollY - navHeight;
      window.scrollTo({ top: yPosition, behavior: 'smooth' });
    }
  }
}
  1. В своих маршрутах укажите все URL-адреса разделов на HomeComponent.

app.route.ts

import { HomeComponent } from './home/home.component';

export const routes: Routes = [
  { path: 'section-1', component: HomeComponent },
  { path: 'section-2', component: HomeComponent },
  { path: 'section-3', component: HomeComponent },
  { path: 'section-4', component: HomeComponent },
  { path: '**', redirectTo: '' },
];
  1. Укажите routes в функции provideRouter.

main.ts

import { routes } from './app/app.routes';

bootstrapApplication(App, {
  providers: [provideAnimations(), provideRouter(routes)],
}).catch((err) => console.error(err));
  1. В настоящее время вы не используете маршрут и не визуализируете компонент. Вам нужно применить <router-outlet> в шаблоне в main.ts. Удалите импорт компонентов раздела из файла App.

main.ts

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    NavComponent,
    CommonModule,
    RouterModule,
  ],
  template: `
  <div class = "container">
     <app-nav></app-nav> 
     <router-outlet></router-outlet>
  </div>
  `,
})

Демо @ StackBlitz