Как правильно расположить фиксированную панель навигации при прокрутке к разделам с одинаковым идентификатором в Angular?

Я работаю над проектом Angular, где у меня есть несколько разделов на странице, каждый из которых имеет уникальный идентификатор. У меня также есть панель навигации с фиксированным положением, которая позволяет пользователям переходить к этим разделам. Моя цель — гарантировать, что когда пользователь нажимает на пункт меню (например, «Раздел2»), навигационная панель выравнивается правильно, как показано на изображении ниже.

Чтобы проиллюстрировать проблему, я создал демо-версию StackBlitz. Однако мне пришлось закомментировать следующую строку <!-- <app-nav></app-nav> --> в демо-версии StackBlitz, чтобы она скомпилировалась:

Демо-версия Stackblitz

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

app.routes.ts

export const routes: Routes = [
  { path: 'section-1', component: Section1Component },
  { path: 'section-2', component: Section2Component },
  { path: 'section-3', component: Section3Component },
  { path: 'section-4', component: Section4Component },
  { path: '**', redirectTo: '' },
];

main.ts

  <div class = "container">
    <!-- <app-nav></app-nav> -->
    <app-section1></app-section1>
    <app-section2></app-section2>
    <app-section3></app-section3>
    <app-section4></app-section4>
  </div>

nav.comComponent.ts

export class NavComponent {
  constructor(private viewportScroller: ViewportScroller) {}

  public scrollToSection(sectionId: string): void {
    this.viewportScroller.scrollToAnchor(sectionId);
  }
}

🤔 А знаете ли вы, что...
CSS позволяет создавать сложные текстовые эффекты, такие как тени и обводки текста.


53
2

Ответы:

попробуйте добавить навигацию в конце за пределами контейнера, чтобы она выглядела так:

<div class = "container">
    <app-section1></app-section1>
    <app-section2></app-section2>
    <app-section3></app-section3>
    <app-section4></app-section4>
</div>
<app-nav></app-nav>

Решено

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

Обратите внимание, что этот подход имеет ограничение: когда прокрутка достигает конца страницы, раздел невозможно закрепить после панели навигации, например <app-section-3> и <app-section-4> (вы можете увидеть ссылку StackBlitz и открыть предварительный просмотр на новой вкладке в полноэкранном режиме). ).

public scrollToSection(sectionId: string): void {
  const element = document.getElementById(sectionId)!;
  const navElement = document.getElementsByTagName('nav')[0]!;

  const navHeight = navElement.offsetHeight;

  const targetPosition = element.getBoundingClientRect().top + window.scrollY;

  this.viewportScroller.scrollToPosition([0, targetPosition - navHeight]);    
}

Альтернативно вы можете поискать ScrollTo, который имеет ту же функциональность и включает анимацию прокрутки.

window.scrollTo({
 left: 0,
 top: targetPosition - navHeight,
 behavior: 'smooth'
});

Демо @ StackBlitz