<link rel="stylesheet" href="styles-3GBANQL6.css">
← Zurück zum Blog

Angular

Aktive Navigationslinks mit Angular-Direktiven verwalten

Aktive Navigationslinks mit Angular-Direktiven verwalten

Heben Sie Ihren aktiven Navigationslink mühelos mit der SectionVisibleDirective hervor

Die Navigation auf einer Website sollte ein reibungsloses und intuitives Erlebnis sein. Ein wichtiger Teil davon ist es, den Benutzern klare visuelle Hinweise zu geben, wo sie sich gerade auf der Seite befinden. Eine gängige Methode, um dies zu erreichen, besteht darin, den aktiven Navigationslink hervorzuheben, während sie durch verschiedene Abschnitte scrollen.

Die SectionVisibleDirective bietet eine einfache und elegante Lösung dafür in Ihren Angular-Anwendungen. Diese Direktive nutzt die Möglichkeiten der Intersection Observer API, um zu erkennen, wann ein Abschnitt sichtbar wird, und aktualisiert entsprechend das Navigationsmenü.

Funktionsweise

Die SectionVisibleDirective funktioniert, indem sie ein bestimmtes HTML-Element, typischerweise einen Abschnitt oder ein Div, beobachtet und eine Aktion auslöst, wenn dieses Element im Sichtbereich sichtbar wird. Hier ist eine Übersicht über den Prozess:

  1. Direktive anhängen: Sie wenden die SectionVisibleDirective auf das gewünschte HTML-Element an, indem Sie das Attribut sectionVisible verwenden. Außerdem geben Sie der Direktive einen eindeutigen sectionName als Eingabe.
  2. Intersection Observer: Die Direktive nutzt die Intersection Observer API, um die Sichtbarkeit des Ziel-Elements zu überwachen. Wenn das Element in den Sichtbereich eintritt (oder einen bestimmten Schwellenwert erreicht), löst der Observer eine Rückruffunktion aus.
  3. Navigationsaktualisierung: Innerhalb der Rückruffunktion kommuniziert die Direktive mit Ihrem Navigationsdienst (z. B. NavService) und übergibt den sectionName. Der Navigationsdienst verwendet diese Informationen dann, um den entsprechenden Link in Ihrem Navigationsmenü hervorzuheben.

Direktiven-Codebeispiel


import {
  AfterViewInit,
  Directive,
  ElementRef,
  inject,
  Inject,
  Input,
  OnDestroy,
  PLATFORM_ID,
} from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Directive({
  selector: '[sectionVisible]',
  standalone: true,
})
export class SectionVisibleDirective implements AfterViewInit, OnDestroy {
  readonly navService: NavService = inject(NavService);
  readonly elementRef: ElementRef = inject(ElementRef);
  private obs!: IntersectionObserver;

  @Input() sectionName!: string;

  constructor(@Inject(PLATFORM_ID) private platform: Object) {}

  ngAfterViewInit() {
    if (isPlatformBrowser(this.platform)) {
      this.hasIntersectionObserver()
        ? this.observerIntersection()
        : this.updateNavMenu();
    }
  }

  private hasIntersectionObserver() {
    return window && 'IntersectionObserver' in window;
  }

  private observerIntersection() {
    this.obs = new IntersectionObserver((entries) => {
      entries.forEach(({ isIntersecting }) => {
        if (isIntersecting) {
          this.updateNavMenu();
        }
      });
    }, { threshold: 0.5 });
    this.obs.observe(this.elementRef.nativeElement);
  }

  private updateNavMenu() {
    this.navService.setMenuSignal(this.sectionName);
  }

  ngOnDestroy(): void {
    this.obs?.disconnect();
  }
}

Fragmentbasierte Routen für One-Pager

Eine der häufigsten Anwendungen dieser Direktive ist in Ein-Seiten-Websites, bei denen verschiedene Abschnitte der Seite mithilfe von fragmentbasierten URLs wie #about, #services oder #contact navigiert werden. Mit der SectionVisibleDirective können Sie den richtigen Navigationslink nahtlos hervorheben, wenn der Benutzer zum entsprechenden Abschnitt scrollt, was klar macht, welcher Teil der Seite gerade angezeigt wird.

HTML-Beispiel:

<nav>
  <a routerLink="/home#home" sectionVisible sectionName="home">Home</a>
  <a routerLink="/home#about" sectionVisible sectionName="about">Über</a>
  <a routerLink="/home#contact" sectionVisible sectionName="contact">Kontakt</a>
</nav>

<section id="home" sectionVisible sectionName="home">
  <h2>Startseite</h2>
  <!-- Inhalt für den Home-Abschnitt -->
</section>

<section id="about" sectionVisible sectionName="about">
  <h2>Über-Abschnitt</h2>
  <!-- Inhalt für den Über-Abschnitt -->
</section>

<section id="contact" sectionVisible sectionName="contact">
  <h2>Kontakt-Abschnitt</h2>
  <!-- Inhalt für den Kontakt-Abschnitt -->
</section>

Erklärung:

  • Die sectionVisible Direktive wird auf jedes <a> Tag in der Navigation und auf jeden <section> auf der Seite angewendet.
  • Die sectionName Eingabe ist auf eine eindeutige Kennung für jeden Abschnitt gesetzt (z. B. "home", "about", "contact").
  • Wenn ein Abschnitt sichtbar wird, benachrichtigt die Direktive den NavService, der dann den entsprechenden Navigationslink hervorhebt.

Verwendung des Schwellenwerts im IntersectionObserver

Der threshold in der Intersection Observer API bestimmt, wie viel eines Elements sichtbar sein muss, bevor der Rückruf des Observers ausgeführt wird. Er wird auf einen Wert zwischen 0 und 1 gesetzt, der den Prozentsatz der Sichtbarkeit des Elements im Sichtbereich darstellt. In der SectionVisibleDirective setzen wir den Schwellenwert auf 0.5, was bedeutet, dass der Rückruf ausgelöst wird, wenn mindestens 50 % des Abschnitts sichtbar sind.

Die Anpassung des Schwellenwerts ermöglicht eine bessere Kontrolle darüber, wann eine Aktion ausgeführt wird. Zum Beispiel würde das Setzen eines Schwellenwerts von 1.0 bedeuten, dass der Rückruf nur ausgeführt wird, wenn der gesamte Abschnitt sichtbar ist, während ein Schwellenwert von 0.0 den Rückruf sofort auslöst, sobald der Abschnitt zu erscheinen beginnt.

Wichtig ist, dass der IntersectionObserver asynchron arbeitet, was bedeutet, dass er den Hauptthread nicht blockiert, im Gegensatz zu traditionellen Scrollereignis-Listenern, die eine ständige Überwachung erfordern. Dies führt zu einer verbesserten Leistung, insbesondere bei größeren oder komplexeren Websites.

Erweiterungen für andere Anwendungsfälle

Während die SectionVisibleDirective perfekt für Ein-Seiten-Anwendungen und fragmentbasierte Routen ist, kann ihre Verwendung leicht auf andere Zwecke ausgeweitet werden. Zum Beispiel könnten Sie sie anpassen für:

  • Lazy Loading von Bildern: Das Laden von Bildern nur auszulösen, wenn sie in den Sichtbereich kommen, reduziert die Ladezeit der Seite und verbessert die Gesamtleistung.
  • Verhaltensverfolgung von Benutzern: Verwenden Sie sie, um Analysedaten zu protokollieren, wenn Benutzer bestimmte Abschnitte Ihrer Seite erreichen, damit Sie Einblicke in ihre Interaktionen mit Ihrem Inhalt gewinnen können.
  • Dynamische Animationen: Animationen oder andere interaktive Elemente erst zu starten, wenn sie kurz davor sind, im Sichtbereich zu erscheinen, um ein ansprechenderes Benutzererlebnis zu schaffen.

Beispiel: Lazy Loading mit IntersectionObserver

Um zu demonstrieren, wie leicht diese Direktive angepasst werden kann, finden Sie hier ein Beispiel, in dem wir sie für das Lazy-Loading von Bildern erweitern. Die Direktive würde das Bild nur laden, wenn es in den Sichtbereich kommt, was die Leistung auf bildlastigen Seiten verbessert.

<img [src]="placeholder" [data-src]="actualSrc" sectionVisible sectionName="image">
  

In diesem Beispiel enthält das Attribut data-src die tatsächliche Bildquelle, die als src-Attribut gesetzt wird, wenn das Bild in den Sichtbereich kommt, wodurch der Platzhalter ersetzt wird.

Vorteile

  • Automatische Hervorhebung: Keine Notwendigkeit für manuelle Ereignis-Listener oder komplexe Scrollberechnungen.
  • Verbessertes Benutzererlebnis: Bietet klare visuelle Rückmeldungen für Benutzer und verbessert die Navigationsklarheit.
  • Leistungsoptimierung: Der Intersection Observer läuft asynchron, wodurch sichergestellt wird, dass der Hauptthread nicht blockiert wird.
  • Einfache Integration: Lässt sich einfach implementieren und in Ihre bestehende Navigationsstruktur oder für andere Anwendungsfälle wie Lazy Loading und Analysedatenverfolgung integrieren.

Die SectionVisibleDirective ist ein leistungsstarkes Werkzeug, um eine benutzerfreundlichere und ansprechendere Website-Erfahrung zu schaffen. Durch die automatische Hervorhebung aktiver Navigationslinks, das Lazy-Loading von Ressourcen oder das Verfolgen von Benutzerinteraktionen können Sie die Benutzer nahtlos durch Ihren Inhalt führen und deren Gesamterlebnis verbessern.

LASSEN SIE UNS ETWAS NEUES BAUEN

Aus Ihrer Idee kann die nächste gute Softwarelösung entstehen.

Erzählen Sie uns, was Sie entwickeln, verbessern oder neu denken möchten.

Projekt besprechen