Держите переполненный div прокрученным вниз, если пользователь не прокрутит вверх
У меня есть div, размер которого составляет всего 300 пикселей, и я хочу, чтобы страница загружалась в нижнюю часть содержимого. Этот div имеет динамически добавленный контент и должен оставаться прокрученным до конца. Теперь, если пользователь решает прокрутить вверх, я не хочу, чтобы он возвращался назад, пока пользователь снова не прокручивается вниз.
Возможно ли иметь div, который будет прокручиваться до самого нижнего уровня, если пользователь не прокручивается, и когда пользователь прокручивается назад, он должен оставаться внизу, даже когда добавляется новый динамический контент. Как бы я пошел, создавая это.
Ответы
Ответ 1
Это может помочь вам:
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
[РЕДАКТИРОВАТЬ], чтобы соответствовать комментарию...
function updateScroll(){
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
}
при каждом добавлении контента вызывайте функцию updateScroll() или устанавливайте таймер:
//once a second
setInterval(updateScroll,1000);
если вы хотите обновить ТОЛЬКО если пользователь не двигался:
var scrolled = false;
function updateScroll(){
if(!scrolled){
var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;
}
}
$("#yourDivID").on('scroll', function(){
scrolled=true;
});
Ответ 2
Я только что реализовал это, и, возможно, вы можете использовать мой подход.
Скажем, у нас есть следующий HTML:
<div id="out" style="overflow:auto"></div>
Затем мы можем проверить, прокручивается ли она до конца с помощью:
var out = document.getElementById("out");
// allow 1px inaccuracy by adding 1
var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;
scrollHeight дает вам высоту элемента, включая любую невидимую область из-за переполнения. clientHeight дает вам высоту CSS или, иначе говоря, фактическую высоту элемента. Оба метода возвращают высоту без margin
, поэтому вам не нужно об этом беспокоиться. scrollTop дает вам положение вертикальной прокрутки. 0 - это верх, а max - это scrollHeight элемента за вычетом самой высоты элемента. При использовании полосы прокрутки может быть трудно (это было в Chrome для меня), чтобы получить полосу прокрутки до самого дна. поэтому я добавил неточность в 1 пиксель. Таким образом, isScrolledToBottom
будет иметь значение true, даже если полоса прокрутки расположена на 1 пиксель снизу. Вы можете установить это так, как считаете нужным.
Тогда это просто вопрос установки scrollTop элемента внизу.
if(isScrolledToBottom)
out.scrollTop = out.scrollHeight - out.clientHeight;
Я сделал для вас скрипку, чтобы показать концепцию: http://jsfiddle.net/dotnetCarpenter/KpM5j/
РЕДАКТИРОВАТЬ: Добавлен фрагмент кода, чтобы уточнить, когда isScrolledToBottom
имеет значение true
.
Прикрепить полосу прокрутки вниз
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>
Ответ 3
Мне удалось получить эту работу только с CSS.
Трюк заключается в использовании display: flex;
и flex-direction: column-reverse;
Браузер рассматривает нижнюю часть как верхнюю. Предполагая, что браузеры, на которые вы нацеливаете поддержку flex-box
, единственное предостережение в том, что разметка должна быть в обратном порядке.
Вот рабочий пример. https://codepen.io/jimbol/pen/YVJzBg
Ответ 4
$('#yourDiv').scrollTop($('#yourDiv')[0].scrollHeight);
Живая демоверсия: http://jsfiddle.net/KGfG2/
Ответ 5
$('#div1').scrollTop($('#div1')[0].scrollHeight);
Or animated:
$("#div1").animate({ scrollTop: $('#div1')[0].scrollHeight}, 1000);
Ответ 6
$('#yourDivID').animate({ scrollTop: $(document).height() }, "slow");
return false;
Это вычислит позицию ScrollTop из высоты #yourDivID
с использованием #yourDivID
$(document).height()
так что даже если динамическое содержимое добавлено в div, скроллер всегда будет в нижней позиции. Надеюсь это поможет. Но он также имеет небольшую ошибку, даже если мы прокручиваем вверх и оставляем указатель мыши на скроллере, он автоматически перейдет в нижнюю позицию. Если кто-то сможет это исправить, это тоже будет хорошо.
Ответ 7
.cont{
height: 100px;
overflow-x: hidden;
overflow-y: auto;
transform: rotate(180deg);
direction:rtl;
text-align:left;
}
ul{
overflow: hidden;
transform: rotate(180deg);
}
<div class="cont">
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
</div>
Ответ 8
//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;
Вот моя версия, основанная на ответе dotnetCarpenter. Мой подход - это чистый jQuery, и я назвал переменные, чтобы сделать вещи немного понятнее. Что происходит, если высота содержимого больше, чем контейнер, мы прокручиваем дополнительное расстояние до достижения желаемого результата.
Работает в IE и хроме.
Ответ 9
Ответ Джима Холла предпочтительнее, потому что, хотя при прокрутке он действительно не прокручивается до самого дна, он также является чистым CSS.
Однако, к сожалению, это нестабильное решение: в chrome (возможно, из-за проблемы 1-px, описанной dotnetCarpenter выше), scrollTop
ведет себя неточно на 1 пиксель, даже без взаимодействия с пользователем (при добавлении элемента). Вы можете установить scrollTop = scrollHeight - clientHeight
, но это будет держать div в положении, когда добавляется другой элемент, иначе функция "держать себя внизу" больше не работает.
Короче говоря, добавление небольшого количества Javascript (вздоха) исправит это и выполнит все требования:
Что-то вроде https://codepen.io/anon/pen/pdrLEZ this (например, Coo), и после добавления элемента в список также следующее:
container = ...
if(container.scrollHeight - container.clientHeight - container.scrollTop <= 29) {
container.scrollTop = container.scrollHeight - container.clientHeight;
}
где 29 - высота одной строки.
Таким образом, когда пользователь прокручивает на половину строки вверх (если это вообще возможно?), Javascript игнорирует его и прокручивает до конца. Но я думаю, что это пренебрежимо мало. И это исправляет Chrome 1 px вещь.
Ответ 10
Вот решение, основанное на сообщении в блоге Райана Ханта. Это зависит от CSS-свойства overflow-anchor
, которое overflow-anchor
позицию прокрутки к элементу в нижней части прокручиваемого содержимого.
const messages = [
'Expect rain today.',
'Tomorrow will be sunny.',
'Snow is coming next week.',
'Hailstorms are imminent.',
];
function addMessage() {
const $message = document.createElement('div');
$message.className = 'message';
$message.innerText = messages[(Math.random() * messages.length) | 0];
$messages.insertBefore($message, $anchor);
// Trigger the scroll pinning when the scroller overflows
if (!overflowing) {
overflowing = isOverflowing($scroller);
$scroller.scrollTop = $scroller.scrollHeight;
}
}
function isOverflowing($el) {
return $el.scrollHeight > $el.clientHeight;
}
const $scroller = document.querySelector('.scroller');
const $messages = document.querySelector('.messages');
const $anchor = document.querySelector('.anchor');
let overflowing = false;
setInterval(addMessage, 1000);
.scroller {
overflow: auto;
height: 90vh;
max-height: 11em;
background: #555;
}
.messages > * {
overflow-anchor: none;
}
.anchor {
overflow-anchor: auto;
height: 1px;
}
.message {
margin: .3em;
padding: .5em;
background: #eee;
}
<section class="scroller">
<div class="messages">
<div class="anchor"></div>
</div>
</section>
Ответ 11
Вот как я подошел к этому. Мой рост div составляет 650 пикселей. Я решил, что если высота прокрутки находится в пределах 150px от нижней части, то автоматически прокручиваю ее. Иначе, оставьте это для пользователя.
if (container_block.scrollHeight - container_block.scrollTop < 800) {
container_block.scrollTo(0, container_block.scrollHeight);
}