Je crée un chat en utilisant des requêtes ajax dans Rails et j'essaye de faire défiler une div vers le bas sans trop de chance.
J'emballe tout dans cette div:
#scroll {
height:400px;
overflow:scroll;
}
Y at-il un moyen de le faire défiler vers le bas par défaut en utilisant JS?
Y at-il un moyen de le faire défiler vers le bas après une requête ajax?
Voici ce que j'utilise sur mon site:
var objDiv = document.getElementById("your_div");
objDiv.scrollTop = objDiv.scrollHeight;
C'est beaucoup plus facile si vous utilisez jQuery:
$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);
en utilisant jQuery animate :
$('#DebugContainer').stop().animate({
scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);
Vous pouvez utiliser le code suivant:
function scrollToBottom(id){
var div = document.getElementById(id);
div.scrollTop = div.scrollHeight - div.clientHeight;
}
Pour effectuer un défilement smooth, utilisez le code suivant (nécessite jQuery):
function scrollSmoothToBottom (id) {
var div = document.getElementById(id);
$('#' + id).animate({
scrollTop: div.scrollHeight - div.clientHeight
}, 500);
}
Voir le sample sur JSFiddle
Et c'est comme ça que ça marche:
Réf: scrollTop , scrollHeight , clientHeight
var mydiv = $("#scroll");
mydiv.scrollTop(mydiv.prop("scrollHeight"));
Fonctionne à partir de jQuery 1.6
Méthode plus récente qui fonctionne sur tous les navigateurs actuels :
this.scrollIntoView(false);
Si vous ne voulez pas compter sur scrollHeight
, le code suivant vous aidera:
$('#scroll').scrollTop(1000000);
Avec jQuery, scrollTop est utilisé pour définir la position verticale de scollbar pour tout élément donné. il existe aussi un plugin Nice jquery scrollTo utilisé pour faire défiler avec animation et différentes options ( démos )
var myDiv = $("#div_id").get(0);
myDiv.scrollTop = myDiv.scrollHeight;
si vous souhaitez utiliser la méthode animate de jQuery pour ajouter une animation tout en faisant défiler l'écran, vérifiez le fragment de code suivant:
var myDiv = $("#div_id").get(0);
myDiv.animate({
scrollTop: myDiv.scrollHeight
}, 500);
J'ai trouvé cela vraiment utile, merci.
Pour les gens 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;
}
]);
Simplement parce que le wrapping dans les éléments jQuery par rapport aux éléments HTML DOM devient un peu déroutant avec angular.
Également pour une application de chat, j'ai jugé utile de faire cette tâche après le chargement de vos chats. Vous devrez peut-être également vous contenter d'un délai d'attente court.
Javascript ou jquery:
var scroll = document.getElementById('messages');
scroll.scrollTop = scroll.scrollHeight;
scroll.animate({scrollTop: scroll.scrollHeight});
Css:
.messages
{
height: 100%;
overflow: auto;
}
petit addenda: ne défile que si la dernière ligne est déjà visible. si le texte défile un tout petit peu, laisse le contenu là où il se trouve (attention: non testé avec des tailles de police différentes. Cela peut nécessiter quelques ajustements dans "> = comparaison"):
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;
Juste comme un extrait de bonus. J'utilise angular et j'essayais de faire défiler un fil de message vers le bas lorsqu'un utilisateur sélectionnait différentes conversations avec les utilisateurs. Pour vous assurer que le défilement fonctionne une fois que les nouvelles données ont été chargées dans le div avec le message ng-repeat pour les messages, enroulez simplement l'extrait de défilement dans un délai.
$timeout(function(){
var messageThread = document.getElementById('message-thread-div-id');
messageThread.scrollTop = messageThread.scrollHeight;
},0)
Cela garantira que l'événement de défilement est déclenché une fois les données insérées dans le DOM.
Cela vous permettra de faire défiler complètement la hauteur du document
$('html, body').animate({scrollTop:$(document).height()}, 1000);
J'ai rencontré le même problème, mais avec une contrainte supplémentaire: je n'avais aucun contrôle sur le code qui ajoutait de nouveaux éléments au conteneur de défilement. Aucun des exemples que j'ai trouvés ici ne m'a permis de faire cela. Voici la solution avec laquelle je me suis retrouvé.
Il utilise Mutation Observers
( https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver ) qui le rend utilisable uniquement sur les navigateurs modernes (bien que des polyfill existent
Donc, fondamentalement, le code ne fait que cela:
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});
J'ai fait un violon pour démontrer le concept: https://jsfiddle.net/j17r4bnk/
Faites défiler jusqu'au dernier élément de la div:
myDiv.scrollTop = myDiv.lastChild.offsetTop
Une méthode très simple consiste à définir le scroll to
à la hauteur du div.
var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);
smooth scroll avec Javascript:
document.getElementById('messages').scrollIntoView({ behavior: 'smooth', block: 'end' });
Je sais que c’est une vieille question, mais aucune de ces solutions n’a fonctionné pour moi. J'ai fini par utiliser offset (). Top pour obtenir les résultats souhaités. Voici ce que j'avais l'habitude de faire doucement faire défiler l'écran vers le bas jusqu'au dernier message de mon application de chat:
$("#html, body").stop().animate({
scrollTop: $("#last-message").offset().top
}, 2000);
J'espère que ça aidera quelqu'un d'autre.