Jak uzyskać pozycję paska przewijania za pomocą Javascript?

190

Próbuję wykryć pozycję paska przewijania przeglądarki za pomocą JavaScript, aby zdecydować, gdzie na stronie jest bieżący widok. Domyślam się, że muszę wykryć, gdzie jest kciuk na ścieżce, a następnie wysokość kciuka jako procent całkowitej wysokości ścieżki. Czy nadmiernie to komplikuję, czy JavaScript oferuje łatwiejsze rozwiązanie? Wszelkie pomysły kodowe?

Paweł
źródło

Odpowiedzi:

209

Możesz użyć element.scrollTopi, element.scrollLeftaby uzyskać odpowiednio przesunięcie pionowe i poziome, które zostało przewinięte. elementmoże być, document.bodyjeśli zależy Ci na całej stronie. Możesz porównać to element.offsetHeighti element.offsetWidth(ponownie, elementmoże być ciało), jeśli potrzebujesz procentów.

Max Shawabkeh
źródło
2
Z jakiej przeglądarki korzystasz? Pobieranie ciała odbywa się inaczej w różnych przeglądarkach ( elementi document.bodybyły tylko przykładami). Szczegółowe informacje można znaleźć na stronie howtocreate.co.uk/tutorials/javascript/browserwindow .
Max Shawabkeh
8
Mam go, aby dać mi poprawną wartość w Firefoksie 3.6 window.pageYOffset, ale nic nie działa na IE7. Próbowaliśmy window.pageYOffset, document.body.scrollTop, document.documentElement.scrollTop,element.scrollTop
Paweł
1
scrollTop działał tylko dla mnie, gdy dodałem nawiasy ... $ (". scrollBody"). scrollTop ()
maia
9
Jeśli masz do czynienia z elementem „window”, możesz użyć window.scrollY zamiast window.scrollTop
Janis Jansen
6
Myślę, że pozycja przewijania nie jest ustawiona document.bodyw większości nowoczesnych przeglądarek - zwykle jest document.documentElementteraz włączona . Zobacz bugs.chromium.org/p/chromium/issues/detail?id=157855 na temat przejścia Chrome.
fzzfzzfzz
134

Zrobiłem to <div>na Chrome.

element .scrollTop - piksele ukryte u góry z powodu przewijania. Bez przewijania jego wartość wynosi 0.

element .scrollHeight - to piksele całego div.

element .clientHeight - to piksele widoczne w przeglądarce.

var a = element.scrollTop;

będzie pozycja.

var b = element.scrollHeight - element.clientHeight;

będzie maksymalną wartością scrollTop .

var c = a / b;

będzie procentem przewijania [od 0 do 1] .

Gatsby
źródło
3
To prawie racja. dla var b powinieneś odejmować window.innerHeight, a nie element.clientHeight.
Kahless,
51
document.getScroll = function() {
    if (window.pageYOffset != undefined) {
        return [pageXOffset, pageYOffset];
    } else {
        var sx, sy, d = document,
            r = d.documentElement,
            b = d.body;
        sx = r.scrollLeft || b.scrollLeft || 0;
        sy = r.scrollTop || b.scrollTop || 0;
        return [sx, sy];
    }
}

zwraca tablicę z dwiema liczbami całkowitymi- [scrollLeft, scrollTop]

Kennebec
źródło
4
Świetnie byłoby pokazać, jak korzystać z tej funkcji na przykładzie.
user18490
1
Myślę, że możesz użyć tego lastscroll = getScroll (); window.scrollTo (lastscroll [0], lastscroll [1]);
Dinesh Rajan
Działa świetnie, ale zmieniłem powrót na obiekt za pomocą klawiszy x i y, ponieważ ma to dla mnie trochę więcej sensu.
xd6_
Edytowano po komentarzu @ user18490.
Davide Cannizzo
ReferenceError: Nie można znaleźć zmiennej: element
Jonny
33

to jest tak :)

window.addEventListener("scroll", function (event) {
    var scroll = this.scrollY;
    console.log(scroll)
});
Brayan Pastor
źródło
11

Odpowiedź na rok 2018 :

Najlepszym sposobem na zrobienie takich rzeczy jest użycie API Intersection Observer API .

Interfejs API Intersection Observer zapewnia sposób na asynchroniczne obserwowanie zmian w przecięciu elementu docelowego z elementem nadrzędnym lub z rzutnią dokumentu najwyższego poziomu.

Historycznie wykrywanie widoczności elementu lub względnej widoczności dwóch elementów względem siebie było trudnym zadaniem, dla którego rozwiązania były niewiarygodne i podatne na powodowanie, że przeglądarka i witryny, do których użytkownik wchodzi, stają się powolne. Niestety, w miarę dojrzewania sieci, zapotrzebowanie na tego rodzaju informacje wzrosło. Informacje o skrzyżowaniach są potrzebne z wielu powodów, takich jak:

  • Leniwe ładowanie obrazów lub innej zawartości podczas przewijania strony.
  • Implementacja stron internetowych z „nieskończonym przewijaniem”, w których coraz więcej treści jest ładowanych i renderowanych podczas przewijania, dzięki czemu użytkownik nie musi przewracać stron.
  • Raportowanie widoczności reklam w celu obliczenia przychodów z reklam.
  • Podejmowanie decyzji, czy wykonać zadania lub procesy animacyjne, na podstawie tego, czy użytkownik zobaczy wynik.

Implementowanie wykrywania skrzyżowań w przeszłości wymagało obsługi zdarzeń i metod wywoływania pętli, takich jak Element.getBoundingClientRect (), w celu zgromadzenia potrzebnych informacji dla każdego elementu, którego dotyczy problem. Ponieważ cały ten kod działa w głównym wątku, nawet jeden z nich może powodować problemy z wydajnością. Gdy witryna jest obciążona tymi testami, wszystko może stać się wręcz brzydkie.

Zobacz następujący przykład kodu:

var options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

var observer = new IntersectionObserver(callback, options);

var target = document.querySelector('#listItem');
observer.observe(target);

Większość współczesnych przeglądarek obsługuje IntersectionObserver , ale powinieneś używać polifillu dla kompatybilności wstecznej.

str
źródło
8

jeśli zależy ci na całej stronie. możesz użyć tego:

document.body.getBoundingClientRect().top

lemospy
źródło
1
zamiast tego użyj document.body
danial dezfouli
3

Jeśli używasz jQuery, jest dla Ciebie idealna funkcja: .scrollTop ()

doc tutaj -> http://api.jquery.com/scrollTop/

Uwaga: możesz użyć tej funkcji do odzyskania LUB ustawienia pozycji.

patrz także: http://api.jquery.com/?s=scroll

Simon the Salmon
źródło
25
Po co odpowiadać na pytanie o JS z biblioteką dla JS, skoro jest to całkowicie możliwe, a nawet wygodne robić to w surowym JS? Po prostu prosisz go, aby dodał dodatkowy czas ładowania, a także zużył trochę miejsca na coś zupełnie niepotrzebnego. Ponadto, od kiedy JavaScript zaczął oznaczać JQuery?
DaemonOfTheWest
4
jeśli pytasz indywidualnie, nigdy nie lubiłem jQuery i nie odpowiedziałem na to pytanie, ale w Vanilla JS są już odpowiedzi udzielone przez innych kolegów, to na czym polega problem, jeśli ktoś dodał smaczną przyprawę w tym wątku. (Wspomniał już, że jeśli używasz jQuery)
Ravinder Payal
@ R01010010 dzieje się tak, ponieważ teraz dni JQuery są bezużyteczne i przynoszą efekt przeciwny do zamierzonego, wszystkie funkcje JQuery są łatwe do zaimplementowania w VanilaJS, a także zależą od tego, co jest w JQuery, z nowymi funkcjami dostępnymi w VanillsaJS, jako programista nie zaktualizujesz się, tylko jako przykład , teraz dni w VanillaJS pojawiło się nowe API o nazwie fetch, które zastąpiło stary XHR, jeśli tylko byłeś w świecie JQuery, nigdy nie zobaczysz korzyści z pobierania i kontynuowania korzystania z jQuery.ajax (). Osobiście uważam, że ludzie, którzy kontynuują korzystanie z JQuery to dlatego, że przestali się uczyć. Również VanillaJS jest szybszy vanilla-js.com
John Balvin Arias
@JohnBalvinArias mówi o pobieraniu, co słychać na ie11, a nawet Edge?
Ben
Popraw mnie, jeśli się mylę, ale pobieranie nie działa poprawnie na „nowoczesnym”, tzn. I jest nadal szeroko stosowane. Gdybym używał jquery, nie byłbym zachęcony do przejścia dalej
Ben
3

Oto inny sposób uzyskania pozycji przewijania

const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
Gor
źródło
0

Myślę, że następująca funkcja może pomóc mieć wartości współrzędnych przewijania:

const getScrollCoordinate = (el = window) => ({
  x: el.pageXOffset || el.scrollLeft,
  y: el.pageYOffset || el.scrollTop,
});

Mam ten pomysł z tą odpowiedź z niewielkimi zmianami.

AmerllicA
źródło