Przewiń do dołu div?


807

Tworzę czat, używając żądań ajax w szynach i próbuję uzyskać div, aby przewinąć do dołu bez większego szczęścia.

Otaczam wszystko w tym div:

#scroll {
    height:400px;
    overflow:scroll;
}

Czy istnieje sposób, aby domyślnie przewijać go do dołu za pomocą JS?

Czy istnieje sposób, aby przewinąć go do dołu po żądaniu ajax?

Odpowiedzi:


1324

Oto, czego używam na mojej stronie:

var objDiv = document.getElementById("your_div");
objDiv.scrollTop = objDiv.scrollHeight;

13
czy ta metoda jest odpowiednia dla wszystkich przeglądarek?
— jondinham,

1
@PaulDinh: Właśnie przyjrzałem się temu i jest problem z IE7 i niższymi przy użyciu scrollHeight. Nie wydaje się być około praca dla IE7 tutaj .
— Sean

2
Dlaczego nie działa po dynamicznym dołączaniu elementów wewnątrz div?
— Vince

3
@Vince - To jednorazowa umowa. Jeśli zmienisz treść, będziesz musiał ponownie wykonać. Polecenie mówi w zasadzie „przenieś pasek przewijania do tej pozycji”.
— DrFriedParts

8
Ponadto, jeśli na przykład masz elementy umieszczone w div, możesz przewinąć określony element do widoku. (tzn. element jest widoczny wewnątrz elementu nadrzędnego div) .. w ten sposób: $ ("#" + instanceID) .scrollTop ($ ("#" + instanceID) [0] .scrollIntoView);
— netfed

360

Jest to o wiele łatwiejsze, jeśli używasz jQuery scrollTop :

$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);

272
Jak to jest łatwiejsze?
— captainspi

78
1 linia zamiast 2? nie ma pojęcia, ale to, co możesz łatwo zrobić za pomocą JQuery, to animacja akcji: $ ("# div-id"). animacja ({scrollTop: $ ("# div-id") [0] .scrollHeight}, 1000 ); mam nadzieję, że to pomoże każdemu :)
— Samuel,

28
potrzebujesz [0], aby uzyskać element dom z elementu jquery, aby uzyskać scrollHeight
— Jimmy Bosse

14
„Nie wspominając już o tym, że JQ jest trudniejszy do odczytania / zrozumienia!” Czysta opinia. Na przykład JQuery jest dla mnie dużo łatwiejszy do czytania, rozumienia i robienia różnych rzeczy. A to rozwiązanie JEST lepsze, jeśli już używasz JQuery.
— Hanna,

47
Bez powtarzania się:$("#mydiv").scrollTop(function() { return this.scrollHeight; });
— Eric

98

Możesz użyć następującego kodu:

function scrollToBottom (id) {
   var div = document.getElementById(id);
   div.scrollTop = div.scrollHeight - div.clientHeight;
}

Aby wykonać płynne przewijanie za pomocą JQuery:

function scrollSmoothToBottom (id) {
   var div = document.getElementById(id);
   $('#' + id).animate({
      scrollTop: div.scrollHeight - div.clientHeight
   }, 500);
}

Zobacz przykład na JSFiddle

Oto dlaczego to działa:

wprowadź opis zdjęcia tutaj

Ref: scrollTop , scrollHeight , clientHeight


92

za pomocą jQuery animate :

$('#DebugContainer').stop().animate({
  scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);

5
Tak powiedział Sam w tym komentarzu . Prawdopodobnie jest to bardziej przydatne w rzeczywistej odpowiedzi!
— Quentin Pradet,

6
Zwróć uwagę, w jaki sposób ta odpowiedź używa .stop () , co zapobiega problemom z wieloma animacjami.
— kalyfe,

Zaskakujące jest to jedyne, które działa dla mnie spośród wszystkich wcześniejszych odpowiedzi. Może to być spowodowane tym, że moje inne div są ustawione wokół warstwy, która musi ciągle przewijać
— Duniyadnd

To był jedyny, który dla mnie zadziałał (
— dodaję


31

Nowsza metoda, która działa we wszystkich obecnych przeglądarkach :

this.scrollIntoView(false);

1
Pomyśl, że działa to tylko w firefox: developer.mozilla.org/en/docs/Web/API/Element/…
— Amrit Kahlon

3
W rzeczy samej brakuje wsparcia, ale jeśli zostanie to zaakceptowane, byłoby wspaniale.
— Kristjan Liiva

Jakieś aktualizacje? Uważam, że należy to zaakceptować jako dobrą odpowiedź. Mam na myśli, chodź na jQuery?
— lkahtz

working: document.querySelector (". mdl-list"). scrollIntoView (false);
— Johann Medina

15

płynne przewijanie za pomocą Javascript:

document.getElementById('messages').scrollIntoView({ behavior: 'smooth', block: 'end' });


8

Jeśli nie chcesz polegać scrollHeight, następujący kod pomaga:

$('#scroll').scrollTop(1000000);

1
Żadne z powyższych rozwiązań, w tym twoje, nie działa w Firefoksie na Androida ... proszę o jakieś przemyślenia?
— Kaya Toast,

Nieważne, użyłem zbyt dużej liczby ( 1E10). Mniejsza liczba działa
— andrewtweber

To zawsze ma znaczenie
— Ben Taliadoros

4
Dlaczego miałoby to być złe działanie? To nie jest tak, że iteruje się po każdym pikselu. Teraz zła praktyka to kolejne pytanie…
— devios1

$ ('# scroll'). scrollTop (Infinity), to też powinno zadziałać.
— Madhav Poudel

5

Za pomocą jQuery scrollTop służy do ustawienia pionowej pozycji paska przewijania dla dowolnego elementu. jest też ładna jquery scrollTo wtyczka używana do przewijania z animacją i różnymi opcjami ( dema )

var myDiv = $("#div_id").get(0);
myDiv.scrollTop = myDiv.scrollHeight;

jeśli chcesz użyć metody animacji jQuery do dodania animacji podczas przewijania w dół, sprawdź następujący fragment:

var myDiv = $("#div_id").get(0);
myDiv.animate({
    scrollTop: myDiv.scrollHeight
  }, 500);

4

Napotkałem ten sam problem, ale z dodatkowym ograniczeniem: nie miałem kontroli nad kodem, który dołączał nowe elementy do kontenera przewijania. Żaden z przykładów, które tu znalazłem, nie pozwolił mi tego zrobić. Oto rozwiązanie, z którym skończyłem.

Wykorzystuje Mutation Observers( https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver ), co sprawia, że ​​można go używać tylko w nowoczesnych przeglądarkach (choć istnieją wielopełniacze)

Zasadniczo kod robi to tak:

var scrollContainer = document.getElementById("myId");

// Define the Mutation Observer
var observer = new MutationObserver(function(mutations) {

  // Compute sum of the heights of added Nodes
  var newNodesHeight = mutations.reduce(function(sum, mutation) {
      return sum + [].slice.call(mutation.addedNodes)
        .map(function (node) { return node.scrollHeight || 0; })
        .reduce(function(sum, height) {return sum + height});
  }, 0);

  // Scroll to bottom if it was already scrolled to bottom
  if (scrollContainer.clientHeight + scrollContainer.scrollTop + newNodesHeight + 10 >= scrollContainer.scrollHeight) {
    scrollContainer.scrollTop = scrollContainer.scrollHeight;
  }

});

// Observe the DOM Element
observer.observe(scrollContainer, {childList: true});

Zrobiłem skrzypce, aby zademonstrować tę koncepcję: https://jsfiddle.net/j17r4bnk/


jak uzyskać dynamiczny identyfikator? jak w <div class="abc"><div data-bind=attr : {'id': myId } ></div></div>tym kodzie myId jest zmienną. Jak mogę uzyskać dostęp do tego identyfikatora w skrypcie.
— Irfan Yusanif,

Nie jestem pewien, czy rozumiem twoje pytanie. W moim przykładzie „myId” jest identyfikatorem kontenera przewijania. Czy chcesz utworzyć więcej niż jeden obszar, w którym użytkownik będzie mógł przewijać?
— Benkinass,

4

JavaScript lub jquery:

var scroll = document.getElementById('messages');
   scroll.scrollTop = scroll.scrollHeight;
   scroll.animate({scrollTop: scroll.scrollHeight});

Css:

 .messages
 {
      height: 100%;
      overflow: auto;
  }

4

Okazało się to bardzo pomocne, dziękuję.

Dla Angulara 1.X:

angular.module('myApp').controller('myController', ['$scope', '$document',
  function($scope, $document) {

    var overflowScrollElement = $document[0].getElementById('your_overflow_scroll_div');
    overflowScrollElement[0].scrollTop = overflowScrollElement[0].scrollHeight;

  }
]);

Tylko dlatego, że zawijanie elementów jQuery w porównaniu do elementów HTML DOM jest nieco mylące z kątowym.

Również w przypadku aplikacji do czatowania stwierdziłem, że wykonanie tego zadania po wczytaniu czatów jest przydatne, być może będziesz musiał także policzkować krótkie przerwy.


3

mały dodatek: przewija tylko, jeśli ostatni wiersz jest już widoczny. po lekkim przewinięciu pozostawia zawartość tam, gdzie jest (uwaga: nie testowano przy różnych rozmiarach czcionek. może to wymagać pewnych korekt wewnątrz „> = porównanie”):

var objDiv = document.getElementById(id);
var doScroll=objDiv.scrollTop>=(objDiv.scrollHeight-objDiv.clientHeight);                   

// add new content to div
$('#' + id ).append("new line at end<br>"); // this is jquery!

// doScroll is true, if we the bottom line is already visible
if( doScroll) objDiv.scrollTop = objDiv.scrollHeight;

3

Podobnie jak fragment kodu bonusowego. Używam kątowego i próbowałem przewinąć wątek wiadomości na dół, gdy użytkownik wybrał różne rozmowy z użytkownikami. Aby upewnić się, że przewijanie działa po załadowaniu nowych danych do div z powtórzeniem ng dla wiadomości, po prostu owiń fragment przewijania w limicie czasu.

$timeout(function(){
    var messageThread = document.getElementById('message-thread-div-id');
    messageThread.scrollTop = messageThread.scrollHeight;
},0)

Dzięki temu zdarzenie przewijania zostanie uruchomione po wstawieniu danych do DOM.


Podejrzewam, że $ scope. $ Apply (callback) działałoby, co wymusza przegląd i ponowną ocenę widoku.
— SStanley,

Dziękuję Ci! Naprawdę zastanawiałem się, dlaczego nie udało mi się sprawić, by zadziałało, a problemem był limit czasu $.
— Wayferer

@Wayferer samesetTimeout(function() { ... }, n)
— KingRider

3

Możesz również, używając jQuery, dołączyć animację do html,bodydokumentu poprzez:

$("html,body").animate({scrollTop:$("#div-id")[0].offsetTop}, 1000);

co spowoduje płynne przewijanie na górę div z identyfikatorem „div-id”.


3

Skrypt Java:

document.getElementById('messages').scrollIntoView(false);

Przewija do ostatniego wiersza obecnej zawartości.


2

Umożliwi to przewinięcie do końca w odniesieniu do wysokości dokumentu

$('html, body').animate({scrollTop:$(document).height()}, 1000);

1

Bardzo prostą metodą jest ustawienie scroll towysokości div.

var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);

1

Przewiń do ostatniego elementu w div:

myDiv.scrollTop = myDiv.lastChild.offsetTop

1

W aplikacji Angular 6 właśnie to zrobiłem:

postMessage() {
  // post functions here
  let history = document.getElementById('history')
  let interval    
  interval = setInterval(function() {
    history.scrollTop = history.scrollHeight
    clearInterval(interval)
  }, 1)
}

Funkcja clearInterval (interwał) zatrzyma stoper, aby umożliwić ręczne przewijanie góra / dół.


1

Mój scenariusz: miałem listę ciągów, w których musiałem dołączyć ciąg podany przez użytkownika i automatycznie przewinąć na koniec listy. Miałem ustaloną wysokość wyświetlania listy, po której powinna się ona przelać.

Próbowałem odpowiedzi @Jeremy Ruten, zadziałało, ale przewijało się do (n-1) elementu. Jeśli ktoś ma tego typu problem, możesz skorzystać z setTimeOut()metody obejścia problemu. Musisz zmodyfikować kod poniżej:

setTimeout(() => {
    var objDiv = document.getElementById('div_id');
    objDiv.scrollTop = objDiv.scrollHeight
}, 0)

Oto utworzony przeze mnie link StcakBlitz, który pokazuje problem i jego rozwiązanie: https://stackblitz.com/edit/angular-ivy-x9esw8


-1

Wiem, że to stare pytanie, ale żadne z tych rozwiązań mi nie wyszło. Skończyło się na użyciu offset (). Top, aby uzyskać pożądane wyniki. Oto, czego użyłem, aby delikatnie przewinąć ekran do ostatniej wiadomości w mojej aplikacji czatu:

$("#html, body").stop().animate({
     scrollTop: $("#last-message").offset().top
}, 2000);

Mam nadzieję, że to pomaga komuś innemu.


-1

Czasami najprostsze jest najlepsze rozwiązanie: nie wiem, czy to pomoże, pomogło mi to przewinąć tam, gdzie chciałem. Im wyższa jest „y =”, tym bardziej przewija się w dół i oczywiście „0” oznacza górę, więc na przykład „1000” może być na dole, „2000” lub „3000” itd., W zależności od tego, jak długo strona jest. Zwykle działa to w przycisku z przyciskiem onclick lub onmouseover.

window.scrollTo(x=0,y=150);

-1

Ustaw odległość od góry przewijanego elementu jako całkowitą wysokość elementu.

const element = this.shadowRoot.getElementById('my-scrollable-div')
element.scrollTop = element.scrollHeight

Nie dodawaj tego samego rozwiązania, jeśli już istnieje.
— Ason

tak, nie rób tego, jeśli rozwiązanie już istnieje
— Oswaldo

-1

Możesz użyć metody HTML DOM scrollIntoView w następujący sposób:

var element = document.getElementById("scroll");
element.scrollIntoView();

-2

posługiwać się :

var element= $('element');
var maxScrollTop = element[0].scrollHeight - element.outerHeight();
element.scrollTop(maxScrollTop);

lub zaznacz przewiń do dołu:

    var element = $(element);
    var maxScrollTop = element[0].scrollHeight - element.outerHeight();
    element.on('scroll', function() {
        if ( element.scrollTop() >= maxScrollTop ) {
            alert('scroll to bottom');
        }
    });

zmień scrollTopMax na var maxScrollTop = element [0] .scrollHeight - element.outerHeight ();
— Mahdi Bagheri,

-2

Jeśli odbywa się to w celu przewinięcia do dołu okna czatu, wykonaj następujące czynności

Pomysł przewinięcia do konkretnego diva na czacie był następujący

1) Każdy dział czatu składający się z Osoby, godziny i wiadomości jest uruchamiany w pętli for z klasą chatContentbox

2) querySelectorAll znajdzie wszystkie takie tablice. Może to być 400 węzłów (400 czatów)

3) przejdź do ostatniego

4) scrollIntoView ()

let lastChatBox = document.querySelectorAll('.chatContentBox'); 
lastChatBox = lastChatBox[lastChatBox.length-1]; 
lastChatBox.scrollIntoView(); 

Podano już kilka odpowiedzi, używając scrollIntoView, więc nie trzeba dodawać jeszcze jednego.
— Ason
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.