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.