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?

dMix
źródło

Odpowiedzi:

1324

Oto, czego używam na mojej stronie:

var objDiv = document.getElementById("your_div");
objDiv.scrollTop = objDiv.scrollHeight;
Jeremy Ruten
źródło
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);
andsien
źródło
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

Chociaż
źródło
92

za pomocą jQuery animate :

$('#DebugContainer').stop().animate({
  scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);
DadViegas
źródło
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ę
36
var mydiv = $("#scroll");
mydiv.scrollTop(mydiv.prop("scrollHeight"));

Działa z jQuery 1.6

https://api.jquery.com/scrollTop/

http://api.jquery.com/prop/

Akira Yamamoto
źródło
1
To rozwiązanie działa dla elementów o unikalnej klasie CSS, ale bez identyfikatora CSS. Rozwiązanie w górnym komentarzu nie działa od razu po wyjęciu z pudełka z klasą CSS.
CFitz
31

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

this.scrollIntoView(false);
tnt-rox
źródło
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' });

adl
źródło
8

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

$('#scroll').scrollTop(1000000);
Benny Neugebauer
źródło
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);
Muhammad Soliman
źródło
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/

Benkinass
źródło
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;
  }
Lay Leangsros
źródło
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.

devonj
źródło
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;
Bruno Jennrich
źródło
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.

Mylescc
źródło
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”.

John Dunne
źródło
3

Skrypt Java:

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

Przewija do ostatniego wiersza obecnej zawartości.

Barath Sankar
źródło
2

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

$('html, body').animate({scrollTop:$(document).height()}, 1000);
Navaneeth
źródło
1

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

var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);
aravk33
źródło
1

Przewiń do ostatniego elementu w div:

myDiv.scrollTop = myDiv.lastChild.offsetTop
Mjaque
źródło
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ół.

moreirapontocom
źródło
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

ngShravil.py
źródło
-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.

BrianLegg
źródło
-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);
SeekLoad
źródło
-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
użytkownik2341537
źródło
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();
Anatol
źródło
-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');
        }
    });
Mahdi Bagheri
źródło
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(); 
veritas
źródło
Podano już kilka odpowiedzi, używając scrollIntoView, więc nie trzeba dodawać jeszcze jednego.
Ason