Wie man einen dezenten Scroll-to-Top-Button erstellt

Avatar of Marcel Rojas
Marcel Rojas am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Ein Button, der zum Seitenanfang zurückführt, ermöglicht es dem Benutzer, schnell und ohne großen Aufwand zum oberen Rand der Seite zurückzukehren. Dies kann sehr nützlich sein, wenn die Seite viele Inhalte hat oder wenn, wie zum Beispiel auf One-Page-Websites, unendliches Scrollen verwendet wird oder auf mobilen Geräten, wo unterschiedliche Bildschirmgrößen dazu führen können, dass sich der Inhalt verlängert.

Diese Buttons schweben normalerweise in der unteren Ecke von Websites und führen dann beim Klicken zurück zum Seitenanfang. Mit JavaScript sind sie ziemlich einfach zu erstellen. Visuell wollen wir, dass er dezent ist, aber dennoch groß genug, um ihn leicht antippen oder anklicken zu können. Schauen wir uns ein paar Möglichkeiten an, wie wir das machen können, angefangen bei einer einfachen Methode und dann mit fortschreitenden Verbesserungen.

Option 1: Halten Sie es einfach

Zuerst wählen wir den Button mit JavaScript aus.

var scrollToTopBtn = document.getElementById("scrollToTopBtn")

Nun gibt document.documentElement das Wurzelelement des Dokuments zurück. Wir benötigen es, um die Offset-Werte zu erhalten. Speichern wir es als Nächstes in einer Variable namens rootElement – das erleichtert den Aufruf im Code.

var rootElement = document.documentElement

Wir fügen dem Button einen Click-Event-Listener hinzu.

function scrollToTop {
  // scroll to top logic
}

scrollToTopBtn.addEventListener("click", scrollToTop)

Dann werden wir ihn innerhalb der Funktion scrollToTop mit der Methode scrollTo zum oberen Bildschirmrand scrollen lassen.

function scrollToTop() {
  // Scroll to top logic
  rootElement.scrollTo({
    top: 0,
    behavior: "smooth"
  })
}

Wir können den Button auch etwas gestalten.

#scrollToTopBtn {
  background-color: black;
  border: none;
  border-radius: 50%;
  color: white;
  cursor: pointer;
  font-size: 16px;
  line-height: 48px;
  width: 48px;
}

Jetzt können wir den Button irgendwo auf der Seite platzieren, zum Beispiel im Footer.

<footer>
  <!-- Scroll to top button -->
  <button id="scrollToTopBtn">☝️</button>
</footer>

Und wir erhalten dies.

Option 2: Erkennen der Scroll-Position

Wir können das Scrollen mit einem Scroll-Event-Listener erkennen.

function handleScroll() {
  // Do something on scroll
}
document.addEventListener("scroll", handleScroll)

Die Funktion handleScroll wird jedes Mal aufgerufen, wenn der Benutzer scrollt. Jetzt benötigen wir die Gesamtzahl der Pixel, die gescrollt werden können.

  • scrollHeight gibt die Höhe eines Elements zurück, einschließlich des Teils, der aufgrund von Überlauf nicht sichtbar ist.
  • clientHeight gibt die innere Höhe eines Elements in Pixeln zurück, also die Höhe des sichtbaren Teils.

Wenn wir scrollHeight von clientHeight subtrahieren, erhalten wir die Gesamtmenge an Pixeln, die gescrollt werden kann.

var scrollTotal = rootElement.scrollHeight - rootElement.clientHeight

Jetzt haben wir eine Variable namens scrollTotal, die die maximale Anzahl von Pixeln darstellt, die vertikal gescrollt werden können. Indem wir die gescrollte Menge durch die Gesamtmenge der scrollbaren Pixel teilen, erhalten wir ein Verhältnis zwischen 0 und 1. Durch Spielen mit diesem Verhältnis können wir den Button einfach ein- und ausschalten.

Zum Beispiel fügen wir eine Bedingung hinzu, die den Scroll-to-Top-Button anzeigt, wenn der Benutzer 80 % (oder ein Verhältnis von 0,80) der gesamten Seitenhöhe nach unten gescrollt hat. 80 % ist eine willkürliche Zahl. Je näher wir an 1 kommen, desto mehr muss der Benutzer scrollen, bevor der Button angezeigt wird.

Hier ist das JavaScript.

var rootElement = document.documentElement


function handleScroll() {
  // Do something on scroll
  var scrollTotal = rootElement.scrollHeight - rootElement.clientHeight
  if ((rootElement.scrollTop / scrollTotal ) > 0.80 ) {
    // Show button
    scrollToTopBtn.classList.add("showBtn")
  } else {
    // Hide button
    scrollToTopBtn.classList.remove("showBtn")
  }
}


document.addEventListener("scroll", handleScroll)

Wir werden etwas CSS benötigen, um den Button korrekt zu positionieren, wenn er sichtbar wird.

.scrollToTopBtn {
  /* same general styles as before */
  
  /* place it at the bottom-right corner */
  position: fixed;
  bottom: 30px;
  right: 30px;


  /* keep it at the top of everything else */
  z-index: 100;


  /* hide with opacity */
  opacity: 0;


  /* also add a translate effect */
  transform: translateY(100px);


  /* and a transition */
  transition: all .5s ease
}


.showBtn {
  opacity: 1;
  transform: translateY(0)
}

Damit erscheint der Button, wenn der Benutzer 80 % der Seite erreicht hat, und verschwindet dann, wenn er darüber liegt.

Das scheint eine großartige Option zu sein, und das Einrichten eines Event-Listeners dafür ist ziemlich einfach. Aber der Performance-Overhead kann teuer werden, da wir ständig die aktuelle Scroll-Position überprüfen.

Es gibt noch eine weitere Option, die sich darum kümmert...

Option 3: Intersection Observer

Die Intersection Observer API ist eine ausgezeichnete Lösung für das obige Problem. Es ist eine ziemlich neue Browser-API, die es Entwicklern ermöglicht, die meisten dieser Aufgaben an den Browser abzugeben, auf eine Weise, die optimierter ist. Travis Almand hat eine gründliche Erklärung dazu verfasst, wie sie funktioniert. Hier ist, wie MDN sie definiert:

Die Intersection Observer API bietet eine Möglichkeit, Änderungen an der Schnittmenge eines Zielelements mit einem Elternelement oder dem Ansichtsfenster eines Top-Level-Dokuments asynchron zu beobachten.

Ziemlich clever! Das bedeutet, dass der Button unser Zielelement sein kann.

// We select the element we want to target
var target = document.querySelector("footer");

Wir schreiben dann eine Callback-Funktion, die etwas tut, wenn unser Element mit dem Ansichtsfenster "überschneidet" – was eine schicke Art ist zu sagen, wenn es sichtbar wird.

Und sobald der Footer in das Ansichtsfenster eintritt oder es verlässt, wollen wir im Grunde nur eine Klasse hinzufügen oder entfernen. Der Callback erhält ein Array von Einträgen als Parameter.

function callback(entries, observer) {
  // The callback will return an array of entries, even if you are only observing a single item
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // Show button
      scrollToTopBtn.classList.add('showBtn')
    } else {
      // Hide button
      scrollToTopBtn.classList.remove('showBtn')
    }
  });
}

Wir müssen eine neue Instanz von IntersectionObserver erstellen und ihr die gerade geschriebene Callback-Funktion übergeben.

let observer = new IntersectionObserver(callback);

Schließlich weisen wir den Observer an, das oben ausgewählte Zielelement zu überwachen (oder besser gesagt: zu beobachten), wenn es mit dem Ansichtsfenster interagiert.

observer.observe(target);

Und wie sieht es mit sanftem Scrollen aus?

Natürlich ist das möglich! Tatsächlich hat Chris uns 2019 gezeigt, wie es mit CSS gemacht werden kann.

<html id="top">
  <body>
     <!-- the entire document -->
     <a href="#top">Jump to top of page</a>
  </body>
</html>
html {
  scroll-behavior: smooth;
}

Es gibt noch *ein wenig* mehr Nuancen dort, wie z. B. Barrierefreiheitsverbesserungen, die Chris ebenfalls in dem Beitrag behandelt. Der Punkt ist, dass CSS neue Fähigkeiten gewinnt, die Dinge erledigen können, für die wir früher JavaScript verwendet haben.


Da haben Sie es! Wir begannen mit einer ziemlich einfachen Idee. Wir haben sie verbessert, indem wir den Button basierend auf der Scroll-Position des Benutzers angezeigt und ausgeblendet haben. Dann verbesserten wir die Leistung, indem wir die Intersection Observer API implementierten, anstatt die aktuelle Scroll-Position zu überwachen. Und schließlich sahen wir, wie CSS für sanftes Scrollen verwendet werden kann. Alles in allem erhalten wir einen Scroll-to-Top-Button, der leicht zu sehen und zu bedienen ist, ohne andere Elemente auf der Seite zu blockieren.