Zum Ende von div scrollen?

808

Ich erstelle einen Chat mit Ajax-Anfragen in Rails und versuche, ein Div dazu zu bringen, ohne viel Glück nach unten zu scrollen.

Ich wickle alles in dieses div:

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

Gibt es eine Möglichkeit, mit JS standardmäßig nach unten zu scrollen?

Gibt es eine Möglichkeit, es nach einer Ajax-Anfrage nach unten zu scrollen?

dMix
quelle

Antworten:

1325

Folgendes verwende ich auf meiner Website:

var objDiv = document.getElementById("your_div");
objDiv.scrollTop = objDiv.scrollHeight;
Jeremy Ruten
quelle
13
Ist diese Methode für alle Browser in Ordnung?
Jondinham
1
@PaulDinh: Ich habe mir das gerade angesehen und es gibt ein Problem mit IE7 und niedriger mit scrollHeight. Es scheint , eine Arbeit um für IE7 zu sein hier .
Sean
3
Warum funktioniert es nicht, nachdem Elemente innerhalb des Div dynamisch angehängt wurden?
Vince
3
@Vince - Es ist ein einmaliger Deal. Wenn Sie den Inhalt ändern, müssen Sie ihn erneut ausführen. Der Befehl lautet im Wesentlichen "Bewegen Sie die Bildlaufleiste an diese Position".
DrFriedParts
8
Wenn Sie beispielsweise Elemente in einem div platziert haben, können Sie ein bestimmtes Element in die Ansicht scrollen. (dh das Element ist im übergeordneten div sichtbar) .. wie folgt: $ ("#" + instanceID) .scrollTop ($ ("#" + instanceID) [0] .scrollIntoView);
netfed
360

Dies ist viel einfacher, wenn Sie jQuery scrollTop verwenden :

$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);
andsien
quelle
273
Wie ist das einfacher?
Captainspi
78
1 Zeile statt 2? Keine Ahnung, aber mit JQuery können Sie die Aktion wie folgt animieren: $ ("# div-id"). animate ({scrollTop: $ ("# div-id") [0] .scrollHeight}, 1000 ); hoffe, das hilft jedem :)
Samuel
28
Sie benötigen [0], um das dom-Element vom jquery-Element zu erhalten, um scrollHeight
Jimmy Bosse zu erhalten.
14
"Ganz zu schweigen davon, dass das JQ schwerer zu lesen / zu verstehen ist!" Rein eine Meinung. Ich finde JQuery zum Beispiel viel einfacher zu lesen, zu verstehen und Dinge damit zu tun. Und diese Lösung ist besser, wenn Sie JQuery ohnehin schon verwenden.
Hanna
47
Ohne sich zu wiederholen:$("#mydiv").scrollTop(function() { return this.scrollHeight; });
Eric
98

Sie können den folgenden Code verwenden:

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

So führen Sie mit JQuery einen reibungslosen Bildlauf durch:

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

Siehe das Beispiel zu JSFiddle

Hier ist, warum dies funktioniert:

Geben Sie hier die Bildbeschreibung ein

Ref: scrollTop , scrollHeight , clientHeight

Tho
quelle
92

Verwenden von jQuery animieren :

$('#DebugContainer').stop().animate({
  scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);
DadViegas
quelle
5
Das hat Sam in diesem Kommentar gesagt . Es ist wahrscheinlich nützlicher in einer tatsächlichen Antwort!
Quentin Pradet
6
Beachten Sie, wie diese Antwort .stop () verwendet , wodurch Probleme mit mehreren Animationen vermieden werden .
Kalyfe
Überraschenderweise ist dies die einzige, die für mich aus allen früheren Antworten heraus funktioniert. Es könnte daran liegen, wie meine anderen Divs um die Ebene herum eingerichtet sind, die weiter scrollen muss
Duniyadnd
Dies war die einzige, die für mich funktioniert hat (ich
füge
36
var mydiv = $("#scroll");
mydiv.scrollTop(mydiv.prop("scrollHeight"));

Funktioniert ab jQuery 1.6

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

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

Akira Yamamoto
quelle
1
Diese Lösung funktioniert für Elemente mit einer eindeutigen CSS-Klasse, jedoch ohne CSS-ID. Die Lösung des Top-Kommentars funktioniert mit einer CSS-Klasse nicht sofort.
CFitz
31

Neuere Methode, die auf allen aktuellen Browsern funktioniert :

this.scrollIntoView(false);
tnt-rox
quelle
1
Denken Sie, dass dies nur auf Firefox funktioniert: developer.mozilla.org/en/docs/Web/API/Element/…
Amrit Kahlon
3
Unterstützung fehlt in der Tat atm, aber wenn dies akzeptiert wird, dann wäre es fantastisch.
Kristjan Liiva
Irgendwelche Updates? Ich denke, dies sollte als gute Antwort akzeptiert werden. Ich meine, komm schon, jQuery?
lkahtz
Arbeiten: document.querySelector (". mdl-list"). scrollIntoView (false);
Johann Medina
15

glatte Schriftrolle mit Javascript:

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

adl
quelle
8

Wenn Sie sich nicht darauf verlassen möchten, scrollHeighthilft der folgende Code:

$('#scroll').scrollTop(1000000);
Benny Neugebauer
quelle
1
Keine der oben genannten Lösungen, einschließlich Ihrer, scheint unter Firefox unter Android zu funktionieren ... irgendwelche Gedanken bitte?
Kaya Toast
Egal, ich habe eine zu große Zahl verwendet ( 1E10). Eine kleinere Anzahl funktioniert
andrewtweber
Es ist immer wichtig
Ben Taliadoros
4
Warum sollte es eine schlechte Leistung sein? Es ist nicht so, als würde es über jedes Pixel iterieren. Jetzt ist schlechtes Üben eine andere Frage…
devios1
$ ('# scroll'). scrollTop (Infinity), dies sollte dann auch funktionieren.
Madhav Poudel
5

Mit jQuery wird scrollTop verwendet, um die vertikale Position der Bildlaufleiste für ein bestimmtes Element festzulegen. Es gibt auch ein nettes jquery scrollTo-Plugin, das zum Scrollen mit Animationen und verschiedenen Optionen ( Demos ) verwendet wird.

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

Wenn Sie die Animationsmethode von jQuery verwenden möchten, um beim Scrollen nach unten eine Animation hinzuzufügen, überprüfen Sie das folgende Snippet:

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

Ich bin auf dasselbe Problem gestoßen, jedoch mit einer zusätzlichen Einschränkung: Ich hatte keine Kontrolle über den Code, mit dem neue Elemente an den Bildlaufcontainer angehängt wurden. Keines der Beispiele, die ich hier gefunden habe, hat mir erlaubt, genau das zu tun. Hier ist die Lösung, mit der ich gelandet bin.

Es verwendet Mutation Observers( https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver ), wodurch es nur in modernen Browsern verwendet werden kann (obwohl Polyfills vorhanden sind).

Im Grunde macht der Code genau das:

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});

Ich habe eine Geige gemacht, um das Konzept zu demonstrieren: https://jsfiddle.net/j17r4bnk/

Benkinass
quelle
Wie bekomme ich eine dynamische ID? wie in <div class="abc"><div data-bind=attr : {'id': myId } ></div></div>In diesem Code ist myId eine Variable. Wie kann ich im Skript auf diese ID zugreifen?
Irfan Yusanif
Ich bin mir nicht ganz sicher, ob ich Ihre Frage verstehe. In meinem Beispiel ist "myId" die ID des Bildlaufcontainers. Möchten Sie mehr als einen Bereich erstellen, in dem der Benutzer scrollen kann?
Benkinass
4

Javascript oder jquery:

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

CSS:

 .messages
 {
      height: 100%;
      overflow: auto;
  }
Lay Leangsros
quelle
4

Fand das wirklich hilfreich, danke.

Für die Angular 1.X-Leute da draußen:

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;

  }
]);

Nur weil das Umschließen von jQuery-Elementen mit HTML-DOM-Elementen ein wenig verwirrend mit eckig wird.

Auch für eine Chat-Anwendung empfand ich es als nützlich, diese Aufgabe nach dem Laden Ihrer Chats zu übernehmen. Möglicherweise müssen Sie auch eine kurze Zeitüberschreitung vornehmen.

Devonj
quelle
3

kleiner Nachtrag: Bildlauf nur, wenn die letzte Zeile bereits sichtbar ist. Wenn ein kleines Bild gescrollt wird, bleibt der Inhalt dort, wo er ist (Achtung: nicht mit unterschiedlichen Schriftgrößen getestet. Dies erfordert möglicherweise einige Anpassungen in "> = Vergleich"):

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
quelle
3

Nur als Bonus-Snippet. Ich verwende Angular und habe versucht, einen Nachrichtenthread nach unten zu scrollen, als ein Benutzer verschiedene Konversationen mit Benutzern ausgewählt hat. Um sicherzustellen, dass der Bildlauf funktioniert, nachdem die neuen Daten mit dem ng-repeat für Nachrichten in das div geladen wurden, schließen Sie das Bildlauf-Snippet einfach in eine Zeitüberschreitung ein.

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

Dadurch wird sichergestellt, dass das Bildlaufereignis ausgelöst wird, nachdem die Daten in das DOM eingefügt wurden.

mylescc
quelle
Ich vermute, dass $ scope. $ Apply (Rückruf) funktionieren würde, da dies eine Zusammenfassung und Neubewertung der Ansicht erzwingt.
SStanley
Vielen Dank! Ich habe mich wirklich gefragt, warum ich es nicht zum Laufen bringen konnte und das $ Timeout war das Problem.
Wayferer
@ Waterferer gleichsetTimeout(function() { ... }, n)
KingRider
3

Sie können mit jQuery auch eine Animation an html,bodydas Dokument anhängen über:

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

Dies führt zu einem reibungslosen Bildlauf zum oberen Rand des Div mit der ID "div-id".

John Dunne
quelle
3

Java Script:

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

Scrollt zur letzten Zeile des vorhandenen Inhalts.

Barath Sankar
quelle
2

Auf diese Weise können Sie in Bezug auf die Dokumenthöhe ganz nach unten scrollen

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

Eine sehr einfache Methode hierfür ist das Einstellen scroll toder Höhe des Div.

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

Scrollen Sie zum letzten Element im div:

myDiv.scrollTop = myDiv.lastChild.offsetTop
mjaque
quelle
1

Bei meiner Angular 6-Anwendung habe ich Folgendes getan:

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

Die Funktion clearInterval (Intervall) stoppt den Timer, um einen manuellen Bildlauf nach oben / unten zu ermöglichen.

moreirapontocom
quelle
1

Mein Szenario: Ich hatte eine Liste mit Zeichenfolgen, in der ich eine von einem Benutzer angegebene Zeichenfolge anhängen und automatisch zum Ende der Liste scrollen musste. Ich hatte eine feste Höhe für die Anzeige der Liste, nach der sie überlaufen sollte.

Ich habe die Antwort von @Jeremy Ruten ausprobiert, es hat funktioniert, aber es wurde zum (n-1) -ten Element gescrollt. Wenn jemand mit dieser Art von Problem konfrontiert ist, können Sie die setTimeOut()Methodenumgehung verwenden. Sie müssen den Code wie folgt ändern:

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

Hier ist der von mir erstellte StcakBlitz-Link, der das Problem und seine Lösung zeigt: https://stackblitz.com/edit/angular-ivy-x9esw8

ngShravil.py
quelle
-1

Ich weiß, dass dies eine alte Frage ist, aber keine dieser Lösungen hat für mich funktioniert. Am Ende habe ich offset (). Top verwendet, um die gewünschten Ergebnisse zu erzielen. Folgendes habe ich verwendet, um den Bildschirm sanft bis zur letzten Nachricht in meiner Chat-Anwendung nach unten zu scrollen :

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

Ich hoffe das hilft jemand anderem.

BrianLegg
quelle
-1

Manchmal ist die einfachste die beste Lösung: Ich weiß nicht, ob dies helfen wird, es hat mir geholfen, dort zu scrollen, wo ich es jemals wollte. Je höher das "y =" ist, desto weiter unten wird gescrollt und natürlich bedeutet "0" oben, so dass beispielsweise "1000" unten oder "2000" oder "3000" usw. sein kann, je nachdem, wie lange Sie sind Seite ist. Dies funktioniert normalerweise in einer Schaltfläche mit onclick oder onmouseover.

window.scrollTo(x=0,y=150);
SeekLoad
quelle
-1

Stellen Sie den Abstand vom oberen Rand des scrollbaren Elements auf die Gesamthöhe des Elements ein.

const element = this.shadowRoot.getElementById('my-scrollable-div')
element.scrollTop = element.scrollHeight
user2341537
quelle
Fügen Sie nicht dieselbe Lösung hinzu, wenn sie bereits vorhanden ist.
Ason
Ja, tu das nicht, wenn die Lösung bereits existiert
Oswaldo
-1

Sie können die HTML DOM scrollIntoView-Methode wie folgt verwenden:

var element = document.getElementById("scroll");
element.scrollIntoView();
Anatol
quelle
-2

verwenden :

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

oder aktivieren Sie den Bildlauf nach unten:

    var element = $(element);
    var maxScrollTop = element[0].scrollHeight - element.outerHeight();
    element.on('scroll', function() {
        if ( element.scrollTop() >= maxScrollTop ) {
            alert('scroll to bottom');
        }
    });
Mahdi Bagheri
quelle
ändere scrollTopMax in var maxScrollTop = element [0] .scrollHeight - element.outerHeight ();
Mahdi Bagheri
-2

Wenn dies zum Scrollen zum Ende des Chat-Fensters durchgeführt wird, gehen Sie wie folgt vor

Die Idee, im Chat zu einem bestimmten Div zu scrollen, war die folgende

1) Jedes Chat-Div, bestehend aus Person, Zeit und Nachricht, wird in einer for-Schleife mit der Klasse chatContentbox ausgeführt

2) querySelectorAll findet alle diese Arrays. Es könnten 400 Knoten sein (400 Chats)

3) gehe zum letzten

4) scrollIntoView ()

let lastChatBox = document.querySelectorAll('.chatContentBox'); 
lastChatBox = lastChatBox[lastChatBox.length-1]; 
lastChatBox.scrollIntoView(); 
veritas
quelle
Es werden bereits mehrere Antworten mit verwendet scrollIntoView, sodass keine weitere hinzugefügt werden muss.
Ason