jQuery / Plugin / jQuery Smooth Scroll

jQuery Smooth Scroll animiert die Navigation zu einem Ziel auf derselben Seite, etwa href="#beta". Wählen Sie Links und rufen Sie .smoothScroll() auf. speed bestimmt die Dauer, offset die Zielkorrektur. Zielfokus und reduzierte Bewegung helfen, die Navigation nach dem visuellen Effekt fortzusetzen.

Umfang und Dateien

Verwendet wird jquery-smooth-scroll von kswedberg, keine ähnlich benannte Mausradbibliothek. Dem Fragment href="#beta" muss eine eindeutige id="beta" im Dokument entsprechen.

Das Beispiel fixiert CDN-Plugin 2.2.0 und vollständiges jQuery 4.0.0. Laden Sie jQuery, Plugin und Initialisierung in dieser Reihenfolge. Slim enthält die benötigten Effekte nicht. Derselbe Plugin-Code wurde mit 4.0.0 und 3.7.1 unter Windows Edge geprüft; das ist keine Freigabe jeder Theme- und Plugin-Kombination.

Nur zwei Menülinks mit .js-scroll werden erweitert. Native jump und der Inhaltslink bleiben nativ und ermöglichen einen Vergleich. Grenzen Sie die Auswahl auf tatsächlich beabsichtigte Seitennavigation ein.

Vollständiges Beispiel mit Fokus und Abstand

Speichern und öffnen Sie UTF-8 als smooth-scroll-demo.html. Server und Build sind nicht nötig; Internet lädt zwei Skripte. Lange Abschnitte und Platz nach dem letzten Ziel machen die Ausrichtung überprüfbar.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Same-page smooth scrolling</title>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-smooth-scroll/2.2.0/jquery.smooth-scroll.min.js"></script>
  <style>
    :root { --anchor-gap: 100px; }
    html { scroll-behavior: auto; }
    body { font: 16px/1.6 sans-serif; margin: 20px; padding-top: var(--anchor-gap); }
    #menu { position: fixed; top: 0; left: 0; right: 0; padding: 12px; background: #e6f4f1; z-index: 10; }
    #menu a, #menu button { display: inline-block; margin: 4px 8px; font: inherit; }
    section { min-height: 700px; max-width: 700px; }
    h2 { scroll-margin-top: var(--anchor-gap); }
    h2:focus { outline: 3px solid teal; }
    footer { min-height: 100vh; }
  </style>
</head>
<body>
  <nav id="menu" aria-label="Sections">
    <a class="js-scroll" href="#alpha">Alpha</a>
    <a class="js-scroll" href="#beta">Beta</a>
    <a href="#native">Native jump</a>
    <button type="button" id="reset">Reset</button>
    <span id="status" role="status">Native links available.</span>
  </nav>
  <h1>Explore the sections</h1>
  <section><h2 id="alpha" tabindex="-1">Alpha</h2><p>First destination. Text remains available without JavaScript.</p></section>
  <section><h2 id="beta" tabindex="-1">Beta</h2><p>Second destination. Tab can continue to <a href="#native">the next destination</a>.</p></section>
  <section><h2 id="native" tabindex="-1">Native destination</h2><p>This menu link is not enhanced by the plugin.</p></section>
  <footer>Enough space to align the last heading below the menu.</footer>
  <script>
    jQuery(function ($) {
      if (typeof $.fn.smoothScroll !== "function") return;
      const $menu = $("#menu"), $status = $("#status"), duration = 600;
      function gap() {
        const value = $menu.outerHeight() + 12;
        document.documentElement.style.setProperty("--anchor-gap", value + "px");
        return value;
      }
      gap(); $(window).on("resize.demo", gap);
      $("#menu a.js-scroll").smoothScroll({
        speed: duration, easing: "swing", autoFocus: true,
        beforeScroll: function (options) {
          options.offset = -gap();
          options.speed = window.matchMedia("(prefers-reduced-motion: reduce)").matches ? 0 : duration;
          $status.text("Moving to " + options.scrollTarget);
        },
        afterScroll: function (options) {
          history.replaceState(null, "", options.scrollTarget);
          $status.text("Arrived at " + options.scrollTarget);
        }
      });
      $("#reset").on("click", function () {
        $("html, body").stop(true, false); window.scrollTo(0, 0);
        history.replaceState(null, "", location.pathname + location.search);
        $status.text("Ready; enhanced links: 2.");
      });
      $status.text("Ready; enhanced links: 2.");
    });
  </script>
</body>
</html>

Nach Initialisierung erscheint diese Anzeige. Ohne JavaScript bleibt Native links available. stehen; die Fragmentlinks funktionieren weiter.

Ready; enhanced links: 2.
  1. Beta bewegt über ungefähr 600ms und meldet Arrived at #beta. Die Überschrift hält 12px unter dem Menü.
  2. Reset stellt Anfang und fragmentlose URL her. Fokussieren Sie Alpha oder Beta per Tastatur und drücken Sie Enter.
  3. Das Ziel erhält einen sichtbaren Fokusrahmen. Nach Beta führt Tab zum Inhaltslink darunter.
  4. Native jump umgeht das Plugin und aktualisiert dessen Ankunftsanzeige nicht.
  5. Mit reduzierter Bewegung reduce wird die Dauer null; Ziel und Abschluss bleiben gleich.
  6. Ändern Sie die Breite bis zum Menüumbruch und prüfen Sie das sichtbare Ziel. Setzen Sie für den Vergleich zurück.

tabindex="-1" erlaubt programmatischen Überschriftenfokus ohne zusätzlichen normalen Tab-Stopp. autoFocus=true versetzt nach Ankunft auch den Tastaturfokus, statt ihn im Menü zu lassen.

Zeit, Koordinaten und URL bestimmen

speed ist hier die Dauer in Millisekunden. Kleinere Werte bewegen dieselbe Strecke schneller. Ändern Sie die duration-Konstante von 600 auf 1200 am selben Ziel und stellen Sie 600 wieder her. Für den Easing-Vergleich ändern Sie nur swing zu linear. Andere Namen brauchen eine passende Erweiterung.

offset wird zur Zielkoordinate addiert. Freiraum oberhalb braucht einen negativen Wert, hier Menühöhe plus 12px mit negativem Vorzeichen. beforeScroll misst erneut und berücksichtigt Umbruch. Positive Werte bewegen weiter abwärts und können die Überschrift unter dem fixierten Menü verstecken.

scroll-margin-top behandelt native Links, während das Plugin einen numerischen offset nutzt. Nehmen Sie nicht an, die CSS-Eigenschaft ändere die Plugin-Koordinaten. Prüfen Sie beide Wege.

Das Plugin verhindert gewöhnlich die Standardaktion. Danach ändert history.replaceState() das Fragment. Es ersetzt den aktuellen Eintrag: Ein Ziel erzeugt keinen zusätzlichen Zurück-Schritt. hashchange-Navigation ist nicht implementiert. Anwendungen mit Zurück/Vorwärts-Anforderungen brauchen eine eigene Verlaufspolitik.

Reset stoppt Effekte und Warteschlange und stellt Position, Fragment und Status zurück. Schnelle Zielwechsel wurden geprüft. Eine Abbruchsteuerung für jedes Mausrad- oder Benutzersignal ist damit nicht implementiert.

CSS-Alternative und Fehlerdiagnose

Für einfache Anker kann scroll-behavior genügen. Folgendes ersetzt das Plugin und wird nicht zusätzlich verwendet. Entfernen Sie beide externen Skripte, Initialisierung, Reset und Statusanzeige. Ersetzen Sie die bestehende html-auto-Regel. Behalten Sie scroll-margin-top und setzen Sie den Abstand passend zur Menühöhe.

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

Damit gelten native Link- und Verlaufsregeln ohne Millisekundenzeit oder Plugin-Callbacks. Die Medienabfrage reduziert Bewegung. Im Plugin-Beispiel steht CSS dagegen auf auto, damit zwei Verfahren nicht konkurrieren.

Bei smoothScroll is not a function prüfen Sie Network-Antworten und Reihenfolge. Ein nachträglich geladenes zweites jQuery kann die Erweiterung verlieren lassen. Unter WordPress prüfen Sie zuerst registrierte Theme-Abhängigkeiten.

Ohne Bewegung prüfen Sie fehlende/doppelte IDs, tatsächliche href-Werte und Auswahl. Bei falscher Ausrichtung kontrollieren Sie Menühöhe, nachladende Bilder oder Schriften und Platz am Dokumentende. Ein innerer Scrollbereich benötigt eigene scrollElement-Konfiguration und Koordinatenprüfung.