Jak mogę sprawdzić, czy element DIV jest przewijany do dołu?

88

Jak określić, bez korzystania z jQuery lub innej biblioteki JavaScript, czy element DIV z pionowym paskiem przewijania jest przewijany do samego dołu?

Moje pytanie nie dotyczy tego, jak przewinąć do dołu. Wiem, jak to zrobić. Chcę sprawdzić, czy element DIV jest już przewinięty na sam dół.

To nie działa:

if (objDiv.scrollTop == objDiv.scrollHeight) 
Bjorn
źródło
zgaduję tutaj, jeśli (objDiv.scrollTop> objDiv.scrollHeight) I może być konieczne zmniejszenie z scrollHeight rozmiaru strzałki przewijania (powiedzmy 20px)
Itay Moav -Malimovka

Odpowiedzi:

109

Jesteś całkiem blisko scrollTop == scrollHeight.

scrollTop odnosi się do górnej części pozycji przewijania, która będzie scrollHeight - offsetHeight

Twoje stwierdzenie if powinno wyglądać tak (nie zapomnij użyć potrójnych równych):

if( obj.scrollTop === (obj.scrollHeight - obj.offsetHeight))
{
}

Edycja: poprawiłem moją odpowiedź, była całkowicie błędna

James Davies
źródło
4
To prawie działa, scrollHeight-offsetHeight nie jest dokładnie taką samą wartością jak scrollTop, ale po wypróbowaniu kodu, jeśli wymagam, aby różnica była mniejsza niż 5 pikseli, aby była dolna, otrzymuję zachowanie, które chcę.
Bjorn
1
to nie jest dokładne. obj.borderWidth należy wziąć pod uwagę
zapętlenie
2
wolę tę odpowiedź: stackoverflow.com/questions/5828275/ ...
Chris,
3
scrollTopmoże być nieintegralna, więc wymaga to pewnej tolerancji (powiedzmy obj.scrollHeight - obj.offsetHeight - obj.scrollTop < 1), aby działać w każdych okolicznościach. Zobacz stackoverflow.com/questions/5828275/…
Chris Martin
może ma to coś wspólnego ze stałymi elementami mojego układu lub czymś innym dziwnym, co robię, ale jedyny moment, w którym ocenia się to jako prawda, to przewijanie do samego początku. To dlatego, że document.body.scrollHeightrówna się document.body.offsetHeightw moim przypadku (Chrome)
Evan de la Cruz
26

Aby uzyskać prawidłowe wyniki, biorąc pod uwagę takie rzeczy, jak możliwość obramowania, poziomego paska przewijania i / lub liczby pływających pikseli, należy użyć ...

el.scrollHeight - el.scrollTop - el.clientHeight < 1

UWAGA: MUSISZ użyć parametru clientHeight zamiast offsetHeight, jeśli chcesz uzyskać prawidłowe wyniki. offsetHeight poda poprawne wyniki tylko wtedy, gdy el nie ma obramowania ani poziomego paska przewijania

Spencer
źródło
Również jedyna odpowiedź, która mi pomogła. Używam dopełnienia, aby ukryć pasek przewijania.
Craig
clientHeight działało naprawdę dobrze. użycie offsetHeight w zaakceptowanej odpowiedzi dało mi wynik, który nie był w 100% dokładny
Finlay Roelofs
eleganckie, dziękuję ... możesz go również używać z Vue w zdarzeniu przewijania, @scroll="scrolling"a następnie w metodach scrolling(event) { event.target // as el in the answer }Powodzenia
Yassine Sedrani
10

Trochę późno na tę imprezę, ale żadna z powyższych odpowiedzi nie wydaje się działać szczególnie dobrze, gdy ...

  • Skalowanie wyświetlacza jest stosowane w systemie operacyjnym dla wyświetlaczy UHD
  • Skalowanie / powiększanie jest stosowane w przeglądarce

Aby uwzględnić wszystkie ewentualności, musisz zaokrąglić w górę obliczoną pozycję przewijania:

Math.ceil(element.scrollHeight - element.scrollTop) === element.clientHeight
Matthew Layton
źródło
Ta odpowiedź jest pierwszą, która działa poprawnie (przetestowałem również odpowiedzi ze stackoverflow.com/q/5828275 ). Jak wspominali inni, w grę wchodzą marginesy, powiększenie i inne czynniki - i wydaje się, że radzi sobie ze wszystkimi. Edycja: poniższa odpowiedź Spencera wydaje się zasadniczo taka sama, również poprawna.
Jan Bradáč
8

Zwraca true, jeśli element znajduje się na końcu swojego przewijania, false, jeśli tak nie jest.

element.scrollHeight - element.scrollTop === element.clientHeight

Mozilla Developer Network

Emmanuel Osimosu
źródło
2
U mnie, używając Chrome, gdzie element to document.body, to nie działa. document.body.scrollHeighti document.bodyclientHeightmają tę samą wartość, więc wyrażenie nigdy nie jest prawdziwe.
Evan de la Cruz,
Jaką edycję możemy zrobić, abyśmy mogli wykryć, że przewijanie znajduje się blisko dołu. Na przykład, jeśli przewijanie jest poniżej 75%, rozważ to blisko dołu
iamsaksham
0
<!DOCTYPE HTML> 
<html> 
<head> 
    <title>JQuery | Detecting when user scrolls to bottom of div. 
    </title> 
</head> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script> 

<body style="text-align:center;" id="body"> 
    <h1 style="color:green;">  
            Data Center  
        </h1> 
    <p id="data_center" style="font-size: 17px; font-weight: bold;"></p> 
    <center> 
        <div class="div" style="width:200px; height:150px; overflow:auto;"> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
            <h1>Hello Friends</h1> 
        </div> 
    </center> 
    <script> 
        $('#data_center').text('Scroll till bottom to get alert!'); 
        jQuery(function($) { 
            $('.div').on('scroll', function() { 
                if ($(this).scrollTop() + $(this).innerHeight() >=  $(this)[0].scrollHeight) {                     
                    alert('End of DIV has reached!'); 
                } 
            }); 
        }); 
    </script> 
</body> 

</html> 

U mnie to działa, mam nadzieję, że to również pomoże. Dzięki.

Kamlesh
źródło
0

Cóż, zadałem sobie to samo pytanie i znalazłem w ten sposób, tutaj umieściłem przykład za pomocą zdarzenia:

let scrollableElement = document.querySelector(".elementScrollable")

scrollableElement.addEventListener("scroll",function(event){
  if(event.target.scrollTop === event.target.scrollTopMax){
        console.log("The scroll arrived at bottom")
  }
})
Elliot Williamson
źródło
0

Ten działa dla mnie. Nieco inne podejście.

if (list.scrollTop + list.clientHeight >= list.scrollHeight - 1) {
    return 'scrollOnTheBottom';
}
Aleks Grunwald
źródło