Scorri fino alla fine del div?


808

Sto creando una chat utilizzando le richieste Ajax nelle rotaie e sto cercando di ottenere un div per scorrere fino in fondo senza molta fortuna.

Sto avvolgendo tutto in questo div:

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

C'è un modo per mantenerlo scorrere verso il basso per impostazione predefinita utilizzando JS?

C'è un modo per mantenerlo scorrere verso il basso dopo una richiesta Ajax?

Risposte:


1325

Ecco cosa uso sul mio sito:

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

13
questo metodo va bene con tutti i browser?
jondinham

1
@PaulDinh: ho appena esaminato questo e c'è un problema con IE7 e inferiore con scrollHeight. Sembra che ci sia un modo per aggirare IE7 qui .
Sean,

3
Perché non funziona dopo aver aggiunto dinamicamente elementi all'interno del div?
Vince,

3
@Vince - È un affare una tantum. Se si modifica il contenuto, sarà necessario rieseguirlo. Il comando sostanzialmente dice "sposta la barra di scorrimento in questa posizione".
DrFriedParts

8
Inoltre, se ad esempio sono presenti degli elementi all'interno di un div, è possibile scorrere un particolare elemento in vista. (ovvero l'elemento è visibile all'interno del div parent) .. in questo modo: $ ("#" + istanzaID) .scrollTop ($ ("#" + istanzaID) [0] .scrollIntoView);
Netfed

360

Questo è molto più semplice se stai usando jQuery scrollTop :

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

273
Come è più facile?
captainspi,

78
1 riga anziché 2? nessun indizio, ma ciò che puoi fare facilmente con JQuery è animare l'azione in questo modo: $ ("# div-id"). animate ({scrollTop: $ ("# div-id") [0] .scrollHeight}, 1000 ); spero che questo aiuti chiunque :)
Samuel

28
è necessario [0] per ottenere l'elemento dom dall'elemento jquery per ottenere scrollHeight
Jimmy Bosse,

14
"Per non parlare del JQ è più difficile da leggere / capire!" Puramente un'opinione. Ad esempio, trovo JQuery molto più facile da leggere, comprendere e fare cose. E questa soluzione è migliore se stai già utilizzando JQuery.
Hanna,

47
Senza ripetere te stesso:$("#mydiv").scrollTop(function() { return this.scrollHeight; });
Eric

98

Puoi usare il seguente codice:

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

Per eseguire uno scorrimento uniforme con JQuery:

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

Vedi l' esempio su JSFiddle

Ecco perché funziona:

inserisci qui la descrizione dell'immagine

Rif: scrollTop , scrollHeight , clientHeight


92

usando jQuery animate :

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

5
Questo è quello che ha detto Sam in questo commento . Tuttavia, è probabilmente più utile in una risposta reale!
Quentin Pradet,

6
Nota come questa risposta utilizza .stop () , che impedisce problemi con più animazioni.
kalyfe,

Sorprendentemente questo è l'unico che funziona per me su tutte le risposte precedenti. Potrebbe essere a causa di come i miei altri div sono impostati attorno al livello che deve continuare a scorrere
Duniyadnd

Questo è stato l'unico che ha funzionato per me (sto aggiungendo immagini, non testo)
john ktejik


31

Metodo più recente che funziona su tutti i browser correnti :

this.scrollIntoView(false);

1
Pensa che
funzioni

3
Il supporto è davvero carente, ma se questo viene accettato, sarebbe fantastico.
Kristjan Liiva,

Nessun aggiornamento? Penso che questo dovrebbe essere accettato come una buona risposta. Voglio dire, andiamo jQuery?
lkahtz,

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

15

scorrimento regolare con Javascript:

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


8

Se non vuoi fare affidamento scrollHeight, il seguente codice aiuta:

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

1
Nessuna delle soluzioni di cui sopra, inclusa la tua, sembra funzionare su Firefox su Android ... qualche idea per favore?
Kaya Toast

Non importa, stavo usando un numero troppo grande ( 1E10). Un numero più piccolo funziona
andrewtweber

Importa sempre
Importa

4
Perché sarebbe una cattiva prestazione? Non è come se stesse iterando su ogni pixel. Ora la cattiva pratica è un'altra domanda ...
devios1

$ ('# scroll'). scrollTop (Infinity), quindi dovrebbe funzionare anche in questo caso.
Madhav Poudel,

5

Usando jQuery, scrollTop viene usato per impostare la posizione verticale di scollbar per un dato elemento. c'è anche un bel plug-in jquery per il plugin utilizzato per scorrere con animazioni e diverse opzioni ( demo )

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

se vuoi usare il metodo animato di jQuery per aggiungere animazione mentre si scorre verso il basso, controllare il frammento seguente:

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

4

Ho riscontrato lo stesso problema, ma con un ulteriore vincolo: non avevo alcun controllo sul codice che aggiungeva nuovi elementi al contenitore di scorrimento. Nessuno degli esempi che ho trovato qui mi ha permesso di fare proprio questo. Ecco la soluzione con cui sono finito.

Utilizza Mutation Observers( https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver ) che lo rende utilizzabile solo su browser moderni (sebbene esistano i polyfill)

Quindi sostanzialmente il codice fa proprio questo:

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

Ho fatto un violino per dimostrare il concetto: https://jsfiddle.net/j17r4bnk/


come ottenere l'ID dinamico? come in <div class="abc"><div data-bind=attr : {'id': myId } ></div></div>In questo codice myId è una variabile. Come posso accedere a questo ID nello script.
Irfan Yusanif,

Non sono sicuro di aver capito la tua domanda. Nel mio esempio, "myId" è l'id del contenitore di scorrimento. Vuoi creare più di un'area in cui l'utente può scorrere?
Benkinass,

4

Javascript o jquery:

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

Css:

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

4

L'ho trovato davvero utile, grazie.

Per la gente di Angular 1.X là fuori:

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;

  }
]);

Solo perché il wrapping degli elementi jQuery rispetto agli elementi DOM HTML diventa un po 'confuso con angolare.

Anche per un'applicazione di chat, ho trovato utile assegnare questo compito dopo che le tue chat sono state caricate, potresti anche doverti dare uno schiaffo anche in un breve timeout.


3

piccolo addendum: scorre solo se l'ultima riga è già visibile. se fatto scorrere un po ', lascia il contenuto dov'è (attenzione: non testato con caratteri di dimensioni diverse. Ciò potrebbe richiedere alcune regolazioni all'interno di "> = confronto"):

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

Proprio come uno snippet bonus. Sto usando angolare e stavo cercando di scorrere un thread di messaggi in fondo quando un utente ha selezionato conversazioni diverse con gli utenti. Per assicurarsi che lo scorrimento funzioni dopo che i nuovi dati sono stati caricati nel div con ng-repeat per i messaggi, basta avvolgere lo snippet di scorrimento in un timeout.

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

Ciò assicurerà che l'evento scroll venga generato dopo che i dati sono stati inseriti nel DOM.


Sospetto che $ scope. $ Apply (callback) funzionerebbe così come questo impone un riassunto e una rivalutazione della vista.
SStanley,

Grazie! Mi stavo davvero chiedendo perché non riuscivo a farlo funzionare e il timeout $ era il problema.
Wayferer,

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

3

Puoi anche, usando jQuery, allegare un'animazione al html,bodydocumento tramite:

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

che si tradurrà in uno scorrimento regolare fino alla cima del div con id "div-id".


3

Script Java:

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

Scorre fino all'ultima riga del contenuto presente.


2

Questo ti permetterà di scorrere fino in fondo per quanto riguarda l'altezza del documento

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

1

Un metodo molto semplice è quello di impostare scroll tol'altezza del div.

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

1

Scorri fino all'ultimo elemento all'interno del div:

myDiv.scrollTop = myDiv.lastChild.offsetTop

1

Nella mia applicazione Angular 6 ho appena fatto questo:

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

La funzione clearInterval (intervallo) fermerà il timer per consentire lo scorrimento manuale in alto / in basso.


1

Il mio scenario: avevo un elenco di stringhe, in cui dovevo aggiungere una stringa fornita da un utente e scorrere automaticamente fino alla fine dell'elenco. Avevo fissato l'altezza della visualizzazione dell'elenco, dopo di che avrebbe dovuto traboccare.

Ho provato la risposta di @Jeremy Ruten, ha funzionato, ma stava scorrendo fino all'elemento (n-1) th. Se qualcuno si trova ad affrontare questo tipo di problema, è possibile utilizzare la setTimeOut()soluzione alternativa al metodo. Devi modificare il codice in basso:

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

Ecco il link StcakBlitz che ho creato che mostra il problema e la sua soluzione: https://stackblitz.com/edit/angular-ivy-x9esw8


-1

So che questa è una vecchia domanda, ma nessuna di queste soluzioni ha funzionato per me. Ho finito usando offset (). Top per ottenere i risultati desiderati. Ecco cosa ho usato per scorrere delicatamente lo schermo fino all'ultimo messaggio nella mia applicazione di chat:

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

Spero che questo aiuti qualcun'altro.


-1

Qualche volta la più semplice è la soluzione migliore: non so se questo possa aiutare, mi ha aiutato a scorrere dove mai volessi. Più è alto "y =", più in basso scorre e ovviamente "0" significa in alto, quindi ad esempio "1000" potrebbe essere in basso, o "2000" o "3000" e così via, a seconda della durata pagina è. Questo di solito funziona in un pulsante con onclick o onmouseover.

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

-1

Imposta la distanza dalla parte superiore dell'elemento scorrevole per essere l'altezza totale dell'elemento.

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

Non aggiungere la stessa soluzione se esiste già.
Ason

sì, non farlo se la soluzione esiste già
Oswaldo,

-1

È possibile utilizzare il metodo scrollIntoView DOM HTML in questo modo:

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

-2

uso :

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

oppure seleziona scorri verso il basso:

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

cambia scrollTopMax in var maxScrollTop = element [0] .scrollHeight - element.outerHeight ();
Mahdi Bagheri,

-2

Se lo si sta facendo per scorrere fino alla fine della finestra di chat, procedere come segue

L'idea di scorrere fino a un particolare div nella chat era la seguente

1) Ogni div chat costituito da persona, ora e messaggio viene eseguito in un ciclo for con classe chatContentbox

2) querySelectorAll trova tutti questi array. Potrebbe essere 400 nodi (400 chat)

3) vai all'ultimo

4) scrollIntoView ()

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

Diverse risposte sono già state fornite, usando scrollIntoView, quindi non è necessario aggiungerne ancora una.
Ason
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.