Gardez overflow div défile vers le bas sauf si l'utilisateur fait défiler vers le haut
J'ai un div de seulement 300 pixels et je le veux lorsque la page se charge vers le bas du contenu. Ce div a du contenu ajouté dynamiquement et doit rester défilé tout le long. Maintenant, si l'utilisateur décide de faire défiler vers le haut, Je ne veux pas qu'il revienne en bas jusqu'à ce que l'utilisateur défile à nouveau
Est-il possible d'avoir un div qui restera défilé vers le bas à moins que l'utilisateur défile vers le haut et quand l'utilisateur défile vers le bas, il a besoin pour se maintenir au fond même lorsque le nouveau contenu dynamique est ajouté. Comment pourrais-je aller au bout de la création de cette.
8 réponses
Bien que cela puisse vous aider:
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
[EDIT], pour correspondre au commentaire...
function updateScroll(){
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
}
Chaque fois que du contenu est ajouté, appelez la fonction updateScroll () ou définissez une minuterie:
//once a second
setInterval(updateScroll,1000);
Si vous souhaitez mettre à jour UNIQUEMENT si l'utilisateur n'a pas bougé:
var scrolled = false;
function updateScroll(){
if(!scrolled){
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
}
}
$("#yourDivID").on('scroll', function(){
scrolled=true;
});
Je viens de mettre en œuvre ceci et peut-être que vous pouvez utiliser mon approche.
Disons que nous avons le HTML suivant:
<div id="out" style="overflow:auto"></div>
Ensuite, nous pouvons vérifier si elle défile vers le bas avec:
var out = document.getElementById("out");
// allow 1px inaccuracy by adding 1
var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;
ScrollHeight Vous donne la hauteur de l'élément, y compris toute zone non visible due à un débordement. clientHeight Vous donne la hauteur CSS ou dit d'une autre manière, la hauteur réelle de l'élément. Les deux méthodes renvoient la hauteur sans margin
, donc vous n'avez pas besoin de vous inquiéter que. scrollTop vous donne la position du défilement verticale. 0 est top et max est la hauteur de défilement de l'élément moins la hauteur de l'élément lui-même. Lorsque vous utilisez la barre de défilement, il peut être difficile (c'était dans Chrome pour moi) d'obtenir la barre de défilement tout en bas. j'ai donc jeté une inexactitude 1px. Donc isScrolledToBottom
sera vrai même si la barre de défilement est 1px du bas. Vous pouvez définir ce à tout ce qui se sent le droit de vous.
Ensuite, il s'agit simplement de définir le scrollTop de l'élément vers le bas.
if(isScrolledToBottom)
out.scrollTop = out.scrollHeight - out.clientHeight;
, j'ai fait du violon pour vous montrer le concept: http://jsfiddle.net/dotnetCarpenter/KpM5j/
Modifier:
Ajout d'un extrait de code pour clarifier quand isScrolledToBottom
est true
.
Coller la barre de défilement vers le bas
const out = document.getElementById("out")
let c = 0
setInterval(function() {
// allow 1px inaccuracy by adding 1
const isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1
const newElement = document.createElement("div")
newElement.textContent = format(c++, 'Bottom position:', out.scrollHeight - out.clientHeight, 'Scroll position:', out.scrollTop)
out.appendChild(newElement)
// scroll to bottom if isScrolledToBottom is true
if (isScrolledToBottom) {
out.scrollTop = out.scrollHeight - out.clientHeight
}
}, 500)
function format () {
return Array.prototype.slice.call(arguments).join(' ')
}
#out {
height: 100px;
}
<div id="out" style="overflow:auto"></div>
<p>To be clear: We want the scrollbar to stick to the bottom if we have scrolled all the way down. If we scroll up, then we don't want the content to move.
</p>
J'ai pu faire fonctionner cela uniquement avec CSS.
, L'astuce est d'utiliser display: flex;
et flex-direction: column-reverse;
Le navigateur traite le bas comme le haut. En supposant que les navigateurs que vous ciblez support flex-box
, la seule mise en garde est que le balisage doit être dans l'ordre inverse.
Voici un exemple de travail. https://codepen.io/jimbol/pen/YVJzBg
$('#yourDiv').scrollTop($('#yourDiv')[0].scrollHeight);
Démo en direct: http://jsfiddle.net/KGfG2/
$('#div1').scrollTop($('#div1')[0].scrollHeight);
Or animated:
$("#div1").animate({ scrollTop: $('#div1')[0].scrollHeight}, 1000);
$('#yourDivID').animate({ scrollTop: $(document).height() }, "slow");
return false;
Cela calculera la Position de ScrollTop à partir de la hauteur de #yourDivID
en utilisant la propriété $(document).height()
de sorte que même si du contenu dynamique est ajouté à la div, le scroller sera toujours à la position inférieure. Espérons que cette aide. Mais il a aussi un petit bug même si nous faisons défiler vers le haut et laisse le pointeur de la souris du défilement, il viendra automatiquement à la position inférieure. Si quelqu'un pouvait corriger cela aussi ce sera bien.
//Make sure message list is scrolled to the bottom
var container = $('#MessageWindowContent')[0];
var containerHeight = container.clientHeight;
var contentHeight = container.scrollHeight;
container.scrollTop = contentHeight - containerHeight;
Voici ma version basée sur la réponse de dotnetCarpenter. Mon approche est une pure jQuery et j'ai nommé les variables pour rendre les choses un peu plus claires.. Ce qui se passe, c'est que si la hauteur du contenu est supérieure au conteneur, nous faisons défiler la distance supplémentaire vers le bas pour obtenir le résultat souhaité.
Fonctionne dans IE et chrome..
La réponse de Jim Hall est préférable car bien qu'elle ne défile pas vers le bas lorsque vous faites défiler vers le haut, c'est aussi du CSS pur.
Malheureusement, ce n'est pas une solution stable: dans chrome (peut-être en raison du problème 1-px décrit par dotnetCarpenter ci-dessus), scrollTop
se comporte incorrectement de 1 pixel, même sans interaction de l'utilisateur (lors de l'ajout d'élément). Vous pouvez définir scrollTop = scrollHeight - clientHeight
, mais cela gardera le div en position lorsqu'un autre élément est ajouté, alias le " keep itself at bas" fonctionnalité ne fonctionne plus.
Donc, en bref, ajouter une petite quantité de Javascript (soupir) va résoudre ce problème et répondre à toutes les exigences:
Quelque chose comme https://codepen.io/anon/pen/pdrLEZ ceci (exemple par Coo), et après avoir ajouté un élément à la liste, aussi ce qui suit:
container = ...
if(container.scrollHeight - container.clientHeight - container.scrollTop <= 29) {
container.scrollTop = container.scrollHeight - container.clientHeight;
}
, Où 29 est la hauteur d'une ligne.
Donc, lorsque l'utilisateur fait défiler une demi-ligne(si cela est même possible?), le Javascript l'ignorera et fera défiler jusqu'au bas. Mais je suppose que c'est neglectible. Et, il corrige le truc Chrome 1 px.