Desplácese hasta la parte inferior de div?


808

Estoy creando un chat usando solicitudes ajax en rieles y estoy tratando de obtener un div para desplazarse hasta el fondo sin mucha suerte.

Estoy envolviendo todo en este div:

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

¿Hay alguna manera de mantenerlo desplazado hacia abajo de forma predeterminada utilizando JS?

¿Hay alguna manera de mantenerlo desplazado hasta el fondo después de una solicitud ajax?

Respuestas:


1326

Esto es lo que uso en mi sitio:

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

13
¿Este método está bien con todos los navegadores?
jondinham

1
@PaulDinh: Acabo de investigar esto y hay un problema con IE7 y versiones inferiores usando scrollHeight. Parece que hay una solución para IE7 aquí .
Sean

3
¿Por qué no funciona después de agregar dinámicamente elementos dentro del div?
Vince

3
@Vince: es un trato único. Si cambia el contenido, deberá volver a ejecutarlo. El comando básicamente dice "mover la barra de desplazamiento a esta posición".
DrFriedParts

8
Y además, si tiene elementos colocados dentro de un div, por ejemplo, puede desplazar un elemento en particular a la vista. (es decir, el elemento es visible dentro del div padre) ... de esta manera: $ ("#" + instanceID) .scrollTop ($ ("#" + instanceID) [0] .scrollIntoView);
netfed

360

Esto es mucho más fácil si está utilizando jQuery scrollTop :

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

273
¿Cómo es esto más fácil?
captainspi

78
1 línea en lugar de 2? no tiene idea, pero lo que puede hacer fácilmente con JQuery es animar la acción de esta manera: $ ("# div-id"). animate ({scrollTop: $ ("# div-id") [0] .scrollHeight}, 1000 ); Espero que esto ayude a cualquiera :)
Samuel

28
necesitas [0] para obtener el elemento dom del elemento jquery para obtener scrollHeight
Jimmy Bosse

14
"¡Sin mencionar que el JQ es más difícil de leer / entender!" Puramente una opinión. Por ejemplo, encuentro que JQuery es mucho más fácil de leer, comprender y hacer cosas. Y esta solución ES mejor si ya está utilizando JQuery de todos modos.
Hanna

47
Sin repetir siempre lo mismo:$("#mydiv").scrollTop(function() { return this.scrollHeight; });
Eric

98

Puedes usar el siguiente código:

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

Para realizar un desplazamiento suave con JQuery:

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

Vea el ejemplo en JSFiddle

He aquí por qué esto funciona:

ingrese la descripción de la imagen aquí

Ref: scrollTop , scrollHeight , clientHeight


92

usando jQuery animate :

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

55
Eso es lo que dijo Sam en este comentario . ¡Sin embargo, probablemente sea más útil en una respuesta real!
Quentin Pradet

66
Observe cómo esta respuesta usa .stop () , que evita problemas con múltiples animaciones.
kalyfe

Sorprendentemente, este es el único que me funciona de todas las respuestas anteriores. Podría ser debido a cómo mis otros divs están configurados alrededor de la capa que necesita seguir desplazándose
Duniyadnd

Este fue el único que funcionó para mí (estoy agregando imágenes, no texto)
John Ktejik


31

Método más nuevo que funciona en todos los navegadores actuales :

this.scrollIntoView(false);

1
Creo que esto solo funciona en firefox: developer.mozilla.org/en/docs/Web/API/Element/…
Amrit Kahlon

3
De hecho, el soporte carece de cajeros automáticos, pero si esto se acepta, sería increíble.
Kristjan Liiva

¿Alguna actualización? Siento que esto debería ser aceptado como la buena respuesta. Quiero decir vamos jQuery?
lkahtz

trabajando: document.querySelector (". mdl-list"). scrollIntoView (falso);
Johann Medina

15

desplazamiento suave con Javascript:

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


8

Si no desea confiar scrollHeight, el siguiente código ayuda:

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

1
Ninguna de las soluciones anteriores, incluida la suya, parece funcionar en Firefox en Android ... ¿alguna idea por favor?
Kaya Toast

No importa, estaba usando un número demasiado grande ( 1E10). Un número menor funciona
andrewtweber

Siempre importa
Ben Taliadoros

44
¿Por qué sería un mal desempeño? No es como si estuviera iterando sobre cada píxel. Ahora la mala práctica es otra pregunta ...
devios1

$ ('# scroll'). scrollTop (Infinity), esto también debería funcionar entonces.
Madhav Poudel

5

Usando jQuery, scrollTop se usa para establecer la posición vertical de la barra de desplazamiento para cualquier elemento dado. También hay un buen complemento jquery scrollTo utilizado para desplazarse con animación y diferentes opciones ( demos )

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

si desea utilizar el método animado de jQuery para agregar animación mientras se desplaza hacia abajo, verifique el siguiente fragmento:

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

4

Me he encontrado con el mismo problema, pero con una restricción adicional: no tenía control sobre el código que agregaba nuevos elementos al contenedor de desplazamiento. Ninguno de los ejemplos que encontré aquí me permitió hacer eso. Aquí está la solución con la que terminé.

Utiliza Mutation Observers( https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver ) lo que lo hace utilizable solo en navegadores modernos (aunque existen polyfills)

Entonces, básicamente, el código hace exactamente eso:

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

Hice un violín para demostrar el concepto: https://jsfiddle.net/j17r4bnk/


¿Cómo obtener la identificación dinámica? como en <div class="abc"><div data-bind=attr : {'id': myId } ></div></div>En este código, myId es una variable. ¿Cómo puedo acceder a esta identificación en el script?
Irfan Yusanif

No estoy seguro de entender tu pregunta. En mi ejemplo, "myId" es la identificación del contenedor de desplazamiento. ¿Desea crear más de un área donde el usuario pueda desplazarse?
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

Encontré esto realmente útil, gracias.

Para la gente de Angular 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;

  }
]);

Solo porque el ajuste en elementos jQuery versus elementos HTML DOM se vuelve un poco confuso con angular.

También para una aplicación de chat, encontré que hacer esta asignación después de que se cargaron sus chats es útil, también es posible que también deba abofetear un breve tiempo de espera.


3

Anexo pequeño: solo se desplaza, si la última línea ya está visible. Si se desplaza un poco, deja el contenido donde está (atención: no probado con diferentes tamaños de fuente. Esto puede necesitar algunos ajustes dentro de "> = comparación"):

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

Solo como un fragmento de bonificación. Estoy usando angular y estaba tratando de desplazar un hilo de mensajes hasta la parte inferior cuando un usuario seleccionaba diferentes conversaciones con los usuarios. Para asegurarse de que el desplazamiento funcione después de que los nuevos datos se hayan cargado en el div con ng-repeat para mensajes, simplemente envuelva el fragmento de desplazamiento en un tiempo de espera.

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

Eso asegurará que el evento de desplazamiento se active después de que los datos se hayan insertado en el DOM.


Sospecho que $ scope. $ Apply (devolución de llamada) funcionaría tan bien como esto obliga a un resumen y una reevaluación de la vista.
SStanley

¡Gracias! Realmente me preguntaba por qué no pude hacerlo funcionar y el tiempo de espera de $ era el problema.
Wayferer

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

3

También puede, usando jQuery, adjuntar una animación al html,bodydocumento a través de:

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

lo que dará como resultado un desplazamiento suave a la parte superior del div con la identificación "div-id".


3

Script Java:

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

Se desplaza a la última línea del contenido presente.


2

Esto te permitirá desplazarte hacia abajo con respecto a la altura del documento

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

1

Un método muy simple para esto es establecer scroll tola altura del div.

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

1

Desplácese hasta el último elemento dentro del div:

myDiv.scrollTop = myDiv.lastChild.offsetTop

1

En mi aplicación Angular 6 acabo de hacer esto:

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

La función clearInterval (intervalo) detendrá el temporizador para permitir el desplazamiento manual arriba / abajo.


1

Mi escenario: tenía una lista de cadenas, en la que tenía que agregar una cadena dada por un usuario y desplazarme al final de la lista automáticamente. Había fijado la altura de la visualización de la lista, después de lo cual debería desbordarse.

Intenté la respuesta de @Jeremy Ruten, funcionó, pero se desplazaba hacia el elemento (n-1). Si alguien se enfrenta a este tipo de problema, puede usar la setTimeOut()solución alternativa del método. Necesita modificar el código a continuación:

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

Aquí está el enlace StcakBlitz que he creado que muestra el problema y su solución: https://stackblitz.com/edit/angular-ivy-x9esw8


-1

Sé que esta es una vieja pregunta, pero ninguna de estas soluciones me funcionó. Terminé usando offset (). Top para obtener los resultados deseados. Esto es lo que solía desplazar suavemente la pantalla hasta el último mensaje en mi aplicación de chat:

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

Espero que esto ayude a alguien más.


-1

A veces, lo más simple es la mejor solución: no sé si esto ayudará, me ayudó a desplazarme donde siempre quise. Cuanto más alto sea "y =", más se desplazará hacia abajo y, por supuesto, "0" significa arriba, por lo que "1000" podría estar abajo, "2000" o "3000", y así sucesivamente, dependiendo de cuánto tiempo la página es Esto generalmente funciona en un botón con onclick o onmouseover.

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

-1

Establezca la distancia desde la parte superior del elemento desplazable para que sea la altura total del elemento.

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

No agregue la misma solución si ya existe.
Asón

sí, no hagas eso si la solución ya existe
Oswaldo

-1

Puede usar el método HTML DOM scrollIntoView de esta manera:

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

-2

utilizar :

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

o verifique desplazarse hacia abajo:

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

cambie scrollTopMax a var maxScrollTop = element [0] .scrollHeight - element.outerHeight ();
Mahdi Bagheri

-2

Si esto se hace para desplazarse hasta la parte inferior de la ventana de chat, haga lo siguiente

La idea de desplazarse a un div particular en el chat fue la siguiente

1) Cada div de chat que consiste en Persona, hora y mensaje se ejecuta en un bucle for con chatcontentbox de clase

2) querySelectorAll encuentra todas esas matrices. Podrían ser 400 nodos (400 chats)

3) ir al último

4) scrollIntoView ()

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

Ya se dan varias respuestas scrollIntoView, por lo que no es necesario agregar una más.
Ason el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.