Porträt von mir (Dmitry Dugarev) - eines jungen Mannes mit Brille, der lächelt und eine Jeansjacke trägt. Er steht vor einem städtischen Hintergrund während der Dämmerung, die Lichter der Stadt sind im Hintergrund verschwommen zu sehen.

Dmitry Dugarev

Website-Entwickler aus Frankfurt am Main

Sanftes Scrollen für Anker-Links in Svelte mit TypeScript

In dieser Schritt-für-Schritt-Anleitung werden wir die smoothScrollTo-Funktion von Grund auf in Svelte und TypeScript erstellen, um eine sanfte Scroll-Animation in Ihrer Webanwendung zu ermöglichen.

Das Bild zeigt eine faszinierende Darstellung von sich mischenden Farben in einer Flüssigkeit, welche eine Art abstrakte Kunst bildet. Man sieht einen Wirbel von intensiven und lebhaften Farben – darunter Töne von Gelb, Lila und Dunkelrot –, die sich in einer unbekannten Flüssigkeit ausbreiten und vermischen. Die Farben fließen in eleganten, rauchartigen Mustern, was eine organische und dynamische Bewegung suggeriert. Die unterschiedliche Dichte und Transparenz der Farben schaffen eine Tiefenillusion, wodurch das Bild eine fast dreidimensionale Qualität erhält. Dieser Effekt erzeugt eine ästhetische und visuell ansprechende Komposition, die die Betrachter zur Interpretation und zum Nachdenken anregt.

Inhalts­verzeichnis

Schritt 1: Projektvorbereitung

Stelle sicher, dass Du ein Svelte-Projekt hast und TypeScript als Sprache verwendest. Falls Du noch kein Svelte-Projekt erstellt habst, kannst Du dies mit dem folgenden Befehl tun:

Bash
npx degit sveltejs/template svelte-app
cd svelte-app

Installieren Sie außerdem die Typen für TypeScript:

Bash
npm install --save-dev @tsconfig/svelte typescript

Schritt 2: Erstellen der smoothScrollTo-Funktion

Erstelle eine neue Datei namens smoothScrollTo.ts im Root-Verzeichnis Deines Projekts. Diese Datei wird unsere smoothScrollTo-Funktion enthalten.

JavaScript
export const smoothScrollTo = (scrollTargetID: string, menuElementID: string, topOffset: number) => {
// Wir füllen die Funktion in den nächsten Schritten...
};

Schritt 3: DOM-Abfrage und Berechnung der Zielposition

Fülle die smoothScrollTo-Funktion mit der ersten Hälfte der Logik. Hier müssen wir die DOM-Abfrage für das scrollTargetID-Element und das menuElementID-Element durchführen. Danach berechnen wir die Zielposition für das Scrollen unter Berücksichtigung der Höhe des Menüs und des topOffset-Werts.

JavaScript
// smoothScrollTo.ts

export const smoothScrollTo = (scrollTargetID: string, menuElementID: string, topOffset: number) => {
    // Query the DOM for the target and menu elements
    const targetElement = document.querySelector(scrollTargetID);
    const menuHeightElement = document.querySelector(menuElementID) as HTMLElement;

    if (targetElement && menuHeightElement) {
        // Get the location of the target element
        const rect = targetElement.getBoundingClientRect();

        // Calculate the target scroll position taking into account the menu's height and provided top offset
        const targetPosition = (rect.top + window.scrollY - menuHeightElement.offsetHeight) === 0
        ? 0
        : (rect.top + window.scrollY - menuHeightElement.offsetHeight - topOffset);

        // The rest of the logic will be filled in the next steps...
    }
};

Schritt 4: Viewport-Höhe und maximale Scroll-Höhe berechnen

Die maximale Scroll-Länge maxScrollHeight ist die Distanz, die der Viewport durchscrollen muss, um ein Zielelement für den Benutzer sichtbar zu machen.

Ein Problem entsteht, wenn sich das Zielelement am Ende der Website befindet. In diesem Fall kann der Viewport nicht bis zur oberen Kante des Zielelements scrollen, da das Dokument bereits endet. Wird dies nicht berücksichtigt, führt es zu einer Animation, die abrupt stoppt, wenn die unterste Kante des Dokuments vom Viewport erreicht wird.

Die Grafik stellt schematisch die Struktur einer Webseite und die Berechnung der Scroll-Distanz dar. Im oberen Bereich ist das gesamte Dokument mit der Beschriftung "Document" und dem Hinweis "Die gesamte Webseite" zu sehen. Ein inneres Rechteck repräsentiert den "ViewPort", also den sichtbaren Bereich, den die Benutzer sehen können, mit der zugehörigen Beschriftung. Innerhalb des Viewports ist ein weiteres Rechteck markiert als "Target" mit der Bezeichnung "Zielelement", welches das Element darstellt, bis zu dem gescrollt wird. Vertikale rote Linien zeigen die Gesamtlänge des Dokuments (document.documentElement.scrollHeight), die Höhe des Viewports (window.innerHeight), die maximale Scroll-Länge (maxScrollHeight) und die Distanz vom oberen Rand des Viewports bis zum Zielelement (offset). Diese Darstellung dient der Veranschaulichung der Zusammenhänge zwischen den verschiedenen Dimensionen und ihrer Relevanz für die Berechnung der Scroll-Distanz auf einer Webseite.

Um dies zu berücksichtigen, wird die maximale Scroll-Länge maxScrollHeight als die gesamte Scroll-Länge document.document­Element.scrollHeight minus der Höhe des Viewports window.innerHeight berechnet. Der Code dafür sieht wie folgt aus:

JavaScript
// smoothScrollTo.ts

export const smoothScrollTo = (scrollTargetID: string, menuElementID: string, topOffset: number) => {
    // Query the DOM for the target and menu elements
    const targetElement = document.querySelector(scrollTargetID);
    const menuHeightElement = document.querySelector(menuElementID) as HTMLElement;

    if (targetElement && menuHeightElement) {
        // Get the location of the target element
        const rect = targetElement.getBoundingClientRect();

        // Calculate the target scroll position taking into account the menu's height and provided top offset
        const targetPosition = (rect.top + window.scrollY - menuHeightElement.offsetHeight) === 0
        ? 0
        : (rect.top + window.scrollY - menuHeightElement.offsetHeight - topOffset);

        // Get the current scroll position
        const currentPosition = window.scrollY;

        // Get the viewport height
        const viewportHeight = window.innerHeight;

        // Calculate the maximum scrollable height
        const maxScrollHeight = document.documentElement.scrollHeight - viewportHeight;

        // The rest of the logic will be filled in the next steps...
    }
};

Schritt 5: Scroll-Distanz berechnen und Animation vorbereiten

Jetzt berechnen wir die Scroll-Distanz und bereiten die Animation vor, indem wir die Dauer und die kubische Ease-in-Out-Funktion festlegen.

JavaScript
// smoothScrollTo.ts

export const smoothScrollTo = (scrollTargetID: string, menuElementID: string, topOffset: number) => {
    // Query the DOM for the target and menu elements
    const targetElement = document.querySelector(scrollTargetID);
    const menuHeightElement = document.querySelector(menuElementID) as HTMLElement;

    if (targetElement && menuHeightElement) {
        // Get the location of the target element
        const rect = targetElement.getBoundingClientRect();

        // Calculate the target scroll position taking into account the menu's height and provided top offset
        const targetPosition = (rect.top + window.scrollY - menuHeightElement.offsetHeight) === 0
        ? 0
        : (rect.top + window.scrollY - menuHeightElement.offsetHeight - topOffset);

        // Get the current scroll position
        const currentPosition = window.scrollY;

        // Get the viewport height
        const viewportHeight = window.innerHeight;



        // Calculate the maximum scrollable height
        const maxScrollHeight = document.documentElement.scrollHeight - viewportHeight;

        let offset = 0;

        // Adjust the target scroll position if it's below the maximum scrollable height
        if (maxScrollHeight < targetPosition) {
            offset = (targetPosition - maxScrollHeight);
        }

        const newTargetPosition = targetPosition - offset;

        // Calculate the distance to scroll
        const distance = newTargetPosition - currentPosition;

        // Get the current time to calculate the animation duration later
        const startTime = Date.now();

        // Calculate the duration of the animation based on the scroll distance
        const duration = Math.max(Math.abs(distance) / 3, 300);

        // The rest of the logic will be filled in the next steps...
    }
};

Schritt 6: Kubische Ease-in-Out-Funktion implementieren und Animation durchführen

Implementiere die kubische Ease-in-Out-Funktion und führe die Animation aus, indem Du window.scroll in Kombination mit requestAnimationFrame verwendest.

JavaScript
// smoothScrollTo.ts

export const smoothScrollTo = (scrollTargetID: string, menuElementID: string, topOffset: number) => {
    // Query the DOM for the target and menu elements
    const targetElement = document.querySelector(scrollTargetID);
    const menuHeightElement = document.querySelector(menuElementID) as HTMLElement;

    if (targetElement &amp;&amp; menuHeightElement) {
        // Get the location of the target element
        const rect = targetElement.getBoundingClientRect();

        // Calculate the target scroll position taking into account the menu's height and provided top offset
        const targetPosition = (rect.top + window.scrollY - menuHeightElement.offsetHeight) === 0
        ? 0
        : (rect.top + window.scrollY - menuHeightElement.offsetHeight - topOffset);

        // Get the current scroll position
        const currentPosition = window.scrollY;

        // Get the viewport height
        const viewportHeight = window.innerHeight;

        // Calculate the maximum scrollable height
        const maxScrollHeight = document.documentElement.scrollHeight - viewportHeight;

        let offset = 0;

        // Adjust the target scroll position if it's below the maximum scrollable height
        if (maxScrollHeight < targetPosition) {
            offset = (targetPosition - maxScrollHeight);
        }

        const newTargetPosition = targetPosition - offset;

        // Calculate the distance to scroll
        const distance = newTargetPosition - currentPosition;

        // Get the current time to calculate the animation duration later
        const startTime = Date.now();

        // Calculate the duration of the animation based on the scroll distance
        const duration = Math.max(Math.abs(distance) / 3, 300);

        // Define the cubic ease-in-out function
        const easeInOutCubic = (t: number, b: number, c: number, d: number) => {
            t /= d / 2;
            if (t < 1) return c / 2 * t * t * t + b;
            t -= 2;
            return c / 2 * (t * t * t + 2) + b;
        };

        // Define the animation frame function
        const animationFrame = () => {
            const currentTime = Date.now();
            // Calculate the time elapsed since the animation started
            const time = Math.min(1, (currentTime - startTime) / duration);

            // Calculate the new scroll position for this animation frame
            const newPosition = easeInOutCubic(time, currentPosition, distance, 1);

            // Scroll to the new position
            window.scroll(0, Math.min(newPosition, maxScrollHeight));

            // Continue the animation if we haven't reached the target position and the max scroll position yet
            if (time < 1 &amp;&amp; newPosition < maxScrollHeight) {
                requestAnimationFrame(animationFrame);
            }
        };

        // Start the animation
        requestAnimationFrame(animationFrame);
    }
};

Schritt 7: Testen

Du hast die smoothScrollTo-Funktion erfolgreich erstellt! Du kannst jetzt die Funktion in Deiner Svelte-Anwendung verwenden, um sanfte Scroll-Effekte zu implementieren. Teste die Funktion, indem Du sie aufrufst und sieh, wie die Seite reibungslos zum angegebenen Element scrollt.

Herzlichen Glückwunsch! Du hast jetzt eine voll funktionsfähige smoothScrollTo-Funktion in Svelte und TypeScript erstellt, um Deine Webanwendung mit einer eleganten Scroll-Animation auszustatten.

Schritt 8: Importieren der Funktion in Deine Anwendung

Öffne die Hauptseite oder das Layout Deiner Svelte-Anwendung (normalerweise App.svelte) und importiere die smoothScrollTo-Funktion.

JavaScript
//App.svelte

<script lang="ts"> 
    import { onMount } from 'svelte'; 
    import { smoothScrollTo } from './smoothScrollTo'; 
</script>

Schritt 9: Verwendung der onMount-Funktion

Verwende die onMount-Funktion von Svelte, um die smoothScrollTo-Funktion aufzurufen, sobald die Komponente geladen ist. Dies ermöglicht das automatische Scrollen, wenn die Seite geladen wird.

JavaScript
<script lang="ts"> 
    import { onMount } from 'svelte'; 
    import { smoothScrollTo } from './smoothScrollTo'; 
    onMount(() => { 
        // Beispiel Verwendung: Scrolle zur 'content'-Sektion, 
        // berücksichtige die Höhe der 'navbar' 
        // und verschiebe die endgültige Position um 20 Pixel von der oberen Kante der 'content'-Sektion 
        smoothScrollTo('content', 'navbar', 20); 
    }); 
</script>

Schritt 10: Ausprobieren

Speichere die Datei und starte die Svelte-Entwicklungs-Server mit dem folgenden Befehl:

Bash
npm run dev

Öffne Dein Webbrowser und navigiere zu Ihrer Svelte-Anwendung. Du solltest das sanfte Scrollen zur angegebenen scrollTargetID-Element sehen, während die Höhe des menuElementID-Elements und der topOffset-Wert berücksichtigt werden.

Herzlichen Glückwunsch! Du hast erfolgreich die smoothScrollTo-Funktion in Deinem Svelte-Projekt implementiert und kannst nun sanfte Scroll-Effekte in Deiner Webanwendung genießen.

Und falls Du weitere Fragen hast, buche gerne eine Website Beratung bei mir. Ich entwickle die Websites mit Svelte und integriere sie in WordPress zur Content-Verwaltung.

Hinterlasse Deine E-Mailerhalte einen Termin + Bonus dazu 🎁

Es ist Zeit, durchzustarten und Deine Website auf das nächste Level zu heben. Hier ist, was wir während der kostenlosen Website Beratung angehen:

Hinterlasse Deine E-Mail und mach den ersten Schritt, um Deine Website zum Magnet für Suchende zu machen!

Gebe Deine E-Mail-Adresse im Format max.mustermann@mail.de ein. Gebe Deine Branche ein, damit ich mich besser auf unser Gespräch vorbereiten kann. Klicke hier, um Deine Terminanfrage zu senden und den Bonus zu erhalten.

P.S.: Bist Du noch am Überlegen? Dann hier ist ein kleiner Anreiz für Dich:

Wenn du die Terminanfrage stellst, und wir uns tatsächlich treffen, bekommst Du:

  • BONUS: Gratis Website Audit - Eine Analyse Deiner Website, die Dir zeigt, wie Du Deine bestehende Website verbessern kannst.

Ich hoffe das reicht. Ich freue mich auf unser Gespräch und bin gespannt, was wir gemeinsam erreichen können!

Meine Unterschrift, die aus einem durchgestrichenen Buchstaben D besteht, der in kyrilischer Schreibschrift geschrieben ist

Beste Grüße
Dmitry Dugarev