scrollIntoView Scrollt einfach zu weit

Lesezeit: 7 Minuten

Ich habe eine Seite, auf der eine Bildlaufleiste mit Tabellenzeilen mit divs darin dynamisch aus der Datenbank generiert wird. Jede Tabellenzeile verhält sich wie ein Link, ähnlich wie Sie es auf einer YouTube-Playlist neben dem Videoplayer sehen würden.

Wenn ein Benutzer die Seite besucht, soll die Option, auf der er sich befindet, an den Anfang des scrollenden Div gehen. Diese Funktionalität funktioniert. Das Problem ist, dass es nur ein bisschen zu weit geht. Als ob die Option, auf der sie sich befinden, etwa 10 Pixel zu hoch ist. Wenn also die Seite besucht wird, wird die URL verwendet, um zu identifizieren, welche Option ausgewählt wurde, und diese Option wird dann an den Anfang des scrollenden Div gescrollt. Hinweis: Dies ist nicht die Bildlaufleiste für das Fenster, sondern ein div mit einer Bildlaufleiste.

Ich verwende diesen Code, um die ausgewählte Option an den Anfang des div zu verschieben:

var pathArray = window.location.pathname.split( "https://stackoverflow.com/" );

var el = document.getElementById(pathArray[5]);

el.scrollIntoView(true);

Es verschiebt es an die Spitze des div, aber etwa 10 Pixel zu weit nach oben. Weiß jemand, wie man das beheben kann?

  • Das Fehlen einer Offset-Konfiguration für scrollIntoView ist beunruhigend.

    – mystrdat

    20. Juli 2017 um 14:21 Uhr

  • @mystrdat Es gibt neue CSS-Eigenschaften, die sich damit befassen, scroll-margin und scroll-padding.

    – Flimmer

    10. Juni 2021 um 15:16 Uhr

Benutzer-Avatar
Arsenij-II

Reibungsloses Scrollen zur richtigen Position (veraltet)

Dort ist der bessere Antwort was nutzt Scroll-Rand und Scroll-Padding CSS-Regeln. getBoundingClientRect in dieser Lösung löst ein zusätzliches erzwungenes Layout aus und kann unnötige Leistungsprobleme verursachen.

Erhalten Korrekt y koordinieren und nutzen window.scrollTo({top: y, behavior: 'smooth'})

const id = 'profilePhoto';
const yOffset = -10; 
const element = document.getElementById(id);
const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;

window.scrollTo({top: y, behavior: 'smooth'});

  • Dies ist die richtigste Antwort – wir können die Position der Schriftrolle leicht mit finden jQuery('#el').offset().top und dann zu verwenden window.scrollTo

    – Alexander Goncharov

    6. Juli 2019 um 23:37 Uhr

  • +1 für diese Lösung. Es hat mir geholfen, richtig zum Element zu scrollen, wenn ich einen Container relativ mit einem oberen Versatz positioniert hatte.

    – Liga

    12. August 2019 um 6:56 Uhr

  • Jeder, der hierher kommt und HashLink mit React Router verwendet, hat bei mir funktioniert. In der Scroll-Prop auf Ihrem HashLink, scroll={el => { const yCoordinate = el.getBoundingClientRect().top + window.pageYOffset; const yOffset = -80; window.scrollTo({ top: yCoordinate + yOffset, behavior: 'smooth' }); }} — wobei der Versatz 10-15 Pixel größer ist als die Größe Ihres Headers, nur um den Abstand zu verbessern

    – Rob B

    4. September 2019 um 14:27 Uhr


  • Das ist die erste Antwort, die mir wirklich geholfen hat

    – Dani Amsalem

    26. Januar 2021 um 22:22 Uhr

  • Nur Problem mit der getBoundingClientRect löst ein erzwungenes Layout / Reflow aus, was einen Leistungsengpass darstellt. Davon abgesehen, wenn es mit parcimony verwendet wird, ist es ganz in Ordnung!

    – GeorgesA

    3. August um 12:26 Uhr

Benutzer-Avatar
Steve Banton

Positionieren Sie den Anker nach der absoluten Methode

Eine andere Möglichkeit, dies zu tun, besteht darin, Ihre Anker genau an der gewünschten Stelle auf der Seite zu positionieren, anstatt sich auf das Scrollen nach Offset zu verlassen. Ich finde, dass es eine bessere Kontrolle für jedes Element ermöglicht (z. B. wenn Sie einen anderen Offset für bestimmte Elemente wünschen) und möglicherweise auch widerstandsfähiger gegen Änderungen/Unterschiede der Browser-API ist.

<div id="title-element" style="position: relative;">
  <div id="anchor-name" style="position: absolute; top: -100px; left: 0"></div>
</div>

Nun wird der Offset relativ zum Element mit -100px angegeben. Erstellen Sie eine Funktion, um diesen Anker für die Wiederverwendung von Code zu erstellen, oder wenn Sie ein modernes JS-Framework wie React verwenden, erstellen Sie dazu eine Komponente, die Ihren Anker rendert, und übergeben Sie den Ankernamen und die Ausrichtung für jedes Element, das möglicherweise oder möglicherweise nicht gleich sein.

Dann verwende einfach:

const element = document.getElementById('anchor-name')
element.scrollIntoView({ behavior: 'smooth', block: 'start' });

Für flüssiges Scrollen mit einem Versatz von 100px.

  • Dies ist bei weitem der beste Weg, dies reibungslos und einfach umzusetzen.

    – Fang22

    3. Oktober 2018 um 16:23 Uhr

  • Die beste und ursprünglichste Methode, denke ich.

    – Даниил Пронин

    17. Juni 2019 um 3:00 Uhr

  • Das ist so einfach und glatt. Viele der anderen fügen einfach unnötiges JS hinzu.

    – RedSands

    27. November 2019 um 23:44 Uhr

  • Dies ist besonders nützlich, wenn sich ein Link vom Typ “Seitenanfang” unter einer Navigationsleiste befindet und Sie die Navigation anzeigen möchten, aber keine anderen Links versetzt haben möchten

    – Joe Mond

    27. März 2020 um 20:17 Uhr

  • Sie können dasselbe mit negativem Rand oben erreichen, Sie vermeiden es, das Element zusammen mit einem anderen mit position relativ zu umbrechen

    – Sergi

    21. April 2020 um 15:15 Uhr

Sie können es in zwei Schritten tun:

el.scrollIntoView(true);
window.scrollBy(0, -10); // Adjust scrolling with a negative value here

  • Wenn die scrollIntoView() hat noch nie zu Ende gescrollt scrollBy() läuft, bricht die letztere Rolle die erstere ab. Zumindest auf Chrome 71.

    – David Hughes

    6. Januar 2019 um 4:04 Uhr


  • Verwenden Sie in diesem Fall das setTimeout, wie in einer Antwort unten gezeigt: stackoverflow.com/a/51935129/1856258 .. Für mich funktioniert es ohne Timeout. Vielen Dank!

    – Leo

    26. Februar 2019 um 13:41 Uhr

  • Gibt es eine Möglichkeit, den Korrektor eines Pixels direkt in scrollIntoView einzufügen, damit sich die Anwendung direkt an die entsprechende Stelle bewegt? Wie scrollIntoView({adjustment:y})ich denke, es sollte mit einem benutzerdefinierten Code am Ende möglich sein

    – Webfrau

    15. Mai 2019 um 17:26 Uhr


Benutzer-Avatar
Lucas Trzesniewski

Wenn es um 10 Pixel geht, könnten Sie den Inhalt einfach manuell anpassen div‘s Scroll-Offset so:

el.scrollIntoView(true);
document.getElementById("containingDiv").scrollTop -= 10;

Benutzer-Avatar
Imtiaz Shakil Siddique

Ich habe dieses Problem gelöst, indem ich verwendet habe,

element.scrollIntoView({ behavior: 'smooth', block: 'center' });

Dadurch erscheint das Element in der center nach dem Scrollen, damit ich nicht rechnen muss yOffset.

Ich hoffe es hilft…

  • Du solltest benutzen scrollTo nicht auf element aber weiter window

    – Arsenij-II

    4. Dezember 2019 um 15:38 Uhr

  • @Arseniy-II Danke für den Hinweis!! Ich habe diesen Teil verpasst!

    – Imtiaz Shakil Siddique

    8. Dezember 2019 um 11:08 Uhr

  • hilft der Block für oben?

    – Ashokkumar Ganesan

    28. April 2020 um 12:41 Uhr

  • Meine Schriftrolle war nur ein bisschen daneben! damit hat es geklappt! Danke!

    – Umer Qureshi

    19. Mai 2021 um 12:46 Uhr

  • Schön, das sollte Top-Kommentar sein!

    – Mango

    24. Mai um 21:09 Uhr

CSS scroll-margin und scroll-padding

Vielleicht möchten Sie einen Blick auf neue CSS-Eigenschaften werfen scroll-padding und scroll-margin. Sie können verwenden scroll-padding für den scrollenden Container (html in diesem Fall) und scroll-margin für das Element innerhalb des Containers.

Für Ihr Beispiel möchten Sie hinzufügen scroll-margin-top für das Element, das Sie anzeigen möchten, wie folgt:

.example {
  scroll-margin-top: 10px;
}

Dies wirkt sich aus scrollIntoView Code, wie dieser Code:

const el = document.querySelector(".example");
el.scrollIntoView({block: "start", behavior: "smooth"});

Dadurch wird das Ansichtsfenster gescrollt, um den oberen Rand des Ansichtsfensters mit dem oberen Rand des Elements auszurichten, jedoch mit 10 Pixel zusätzlichem Platz. Mit anderen Worten, diese Eigenschaften des Elements werden berücksichtigt:

  • padding-top
  • border-top
  • scroll-margin-top
  • (und nicht margin-top)

Außerdem, wenn die html Element hat scroll-padding-top gesetzt, dann wird auch das berücksichtigt.

  • Du solltest benutzen scrollTo nicht auf element aber weiter window

    – Arsenij-II

    4. Dezember 2019 um 15:38 Uhr

  • @Arseniy-II Danke für den Hinweis!! Ich habe diesen Teil verpasst!

    – Imtiaz Shakil Siddique

    8. Dezember 2019 um 11:08 Uhr

  • hilft der Block für oben?

    – Ashokkumar Ganesan

    28. April 2020 um 12:41 Uhr

  • Meine Schriftrolle war nur ein bisschen daneben! damit hat es geklappt! Danke!

    – Umer Qureshi

    19. Mai 2021 um 12:46 Uhr

  • Schön, das sollte Top-Kommentar sein!

    – Mango

    24. Mai um 21:09 Uhr

Benutzer-Avatar
schettino72

Dies funktioniert für mich in Chrome (mit reibungslosem Scrollen und ohne Timing-Hacks)

Es bewegt nur das Element, initiiert den Bildlauf und bewegt es dann zurück.

Es gibt kein sichtbares “Popping”, wenn sich das Element bereits auf dem Bildschirm befindet.

pos = targetEle.style.position;
top = targetEle.style.top;
targetEle.style.position = 'relative';
targetEle.style.top = '-20px';
targetEle.scrollIntoView({behavior: 'smooth', block: 'start'});
targetEle.style.top = top;
targetEle.style.position = pos;

  • Dies ist die beste Lösung … Ich wünschte, es wäre als Antwort markiert. Hätte ein paar Stunden gespart.

    – Schiwam

    16. August 2020 um 14:46 Uhr

  • Getestet und es funktioniert out of the box. Kein Hack und funktioniert super! Stimmen Sie ab!

    – Jens Törnell

    14. September 2020 um 15:20 Uhr

  • Toll. Auf diese Weise (Speichern von style.top, Setzen auf -x und späteres erneutes Anwenden nach scrollIntoView) ist das einzige, was in Blazor funktioniert und tatsächlich funktioniert. Die Verwendung mit der Virtualize-Komponente, um viele Daten anzuzeigen. War schockiert zu erfahren, dass es kein Scrollen gibt mit allen Mitteln unterstützt!!Danke

    – Dieser Marc

    21. Juli 2021 um 0:27 Uhr

  • Perfekt!! Ich musste mich anmelden um dich zu liken :)))

    – Triet Pham

    5. Januar um 16:57 Uhr

1298580cookie-checkscrollIntoView Scrollt einfach zu weit

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy