Я задал похожий вопрос вчера, но плохо объяснил, и не указал мое желание чисто CSS-решения, которое, я думаю, должно быть возможным, поэтому я пытаюсь снова.
По сути, у меня есть проблема, где у меня есть div прокручиваемых сообщений и поле ввода под ним. Когда я нажимаю кнопку, я бы хотел, чтобы поле ввода увеличилось на 100 пикселей, без прокрутки div сообщений.
Вот скрипка, которая демонстрирует проблему в полном объеме
Как вы можете видеть, когда вы нажимаете кнопку «Добавить поле», div сообщений также прокручивается вверх. Я бы хотел, чтобы он остался там, где был. Точно так же, если вы слегка прокручиваетесь, чтобы видеть только второе-последнее сообщение, нажатие кнопки должно аналогичным образом сохранить эту позицию при нажатии.
Интересно то, что это поведение «иногда» сохраняется. Например, в некоторых обстоятельствах (которые я не могу точно вывести) позиция прокрутки сохраняется. Я просто хотел бы, чтобы он постоянно вел себя как таковой.
window.onload = function(e) {
document.querySelector(".messages").scrollTop = 10000;
};
function test() {
document.querySelector(".send-message").classList.toggle("some-margin");
}
.container {
width: 400px;
height: 300px;
border: 1px solid #333;
display: flex;
flex-direction: column;
}
.messages {
overflow-y: auto;
height: 100%;
}
.send-message {
width: 100%;
display: flex;
flex-direction: column;
}
.some-margin {
margin-bottom: 100px;
}
<div class="container">
<div class="messages">
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
</div>
<div class="send-message">
<input />
</div>
</div>
<button onclick="test()">add margin</button>
div
прокручивается вверх, а уменьшается высота div. Так почему это важно? Ну, это означает, что онscrollbar
не корректирует свою позицию. Полоса прокрутки запоминает только свое положение относительно верхней части контейнера. Когда высота div уменьшается, кажется, что полоса прокрутки прокручивается вверх, но на самом деле это не так.Ответы:
Это забавное решение, которое вам может понравиться.
Что мы знаем о div, так это то, что он сохраняет только верхнюю позицию полосы прокрутки, поэтому, если высота изменилась по какой-либо причине, полоса прокрутки останется прежней, и это является причиной вашей проблемы.
В качестве обходного пути вы можете перевернуть
.messages
180 градусов с помощьюtransform: rotate(180deg) scaleX(-1);
и откинуть назад,.message
чтобы отменить перелистывание контента, тогда div будет поддерживать нижнюю полосу прокрутки (которая является верхней) автоматически.источник
Нормальное поведение полосы прокрутки - она должна быть наверху, поэтому, когда вы устанавливаете ее на нижнюю часть при загрузке страницы, вы должны поддерживать ее самостоятельно, потому что когда когда-либо нижний контент нажимает ее, div scroll перемещается наверх.
Итак, у меня есть два решения для вас:
Переверните сообщения внутри div сообщений, чтобы последнее сообщение было первым, чтобы прокрутка всегда была сверху.
Я создал функцию javascript для прокрутки до нижней части любого элемента, поэтому вы просто вызываете ее, когда хотите прокрутить до нижней части.
Проверьте фрагмент
источник
Вы можете сделать это наоборот, задав высоту
.messages
вместо, вместо того, чтобы передавать ее.container
в этом случае, это не повлияет на сообщения,div
но если вы передадите ее,.container
это подтолкнет ваш div, потому что поле находится внутри основного div, которые имеют высоту.Проверьте этот фрагмент
источник
.send-message
. Если вы посмотрите на мой предыдущий вопрос, то это сделано потому, что это похоже на удар по марже от открытия виртуальной клавиатуры на мобильных устройствах (нижняя часть поля - всего лишь замена 1: 1 для отладки решения)Простой обходной путь - установить предыдущий
scrollTop
переключатель. Здесь я использую набор данных для хранения предыдущегоscrollTop
значения, вы также можете использовать переменную.источник
Я имею в виду следующее - это решение только для CSS, которое решает именно ваш пример:
но я не думаю, что это поможет вам с вашей первоначальной проблемой виртуальной клавиатуры. Но, возможно, это может вдохновить кого-то другого на решение.
Основная проблема заключается в том, что полоса прокрутки уже делает именно то, что вы хотите:
Сохранение своей позиции, чтобы последний прочитанный контент был виден.
За исключением полосы прокрутки решает, что вы хотите видеть верхнюю часть видимого в данный момент контента, а не нижнюю. (Это проще увидеть, если вы используете цифры: https://jsfiddle.net/1co3x48n/ )
Если вы хотите использовать javascript, есть ответы на все вопросы: https://www.google.com/search?q=scrollbar+always+on+bottom+css+site:stackoverflow.com
Честно говоря, тот факт, что вы можете просмотреть ~ 3+ страниц этого и найти только ответы Javascript, говорит мне, что вы не найдете ответ только для CSS, конечно же, не тот, который широко совместим с браузером.
источник
К сожалению, ни одно из предложенных решений не работает. Проблема с использованием
onFocus
текстового поля заключается в том, что он не будет применяться, если текстовое поле уже имеет фокус. Я возился с этим часами, и самое близкое решение, которое я нашел, это:Тем не менее, это только кажется, иногда работает. Он работает 100% времени при нажатии на текстовое поле, но по какой-то причине при закрытии виртуальной клавиатуры он работает только в том случае, если он был прокручен достаточно. В противном случае он каждый раз сбрасывается в одну и ту же позицию (около дна, но не совсем внизу).
Не уверен, что это вызывает. Завтра мне придется расследовать больше. Пока это самый близкий.
источник
Создайте контейнер, как в приведенных выше примерах, но затем просто измените CSS, когда начнете печатать.
Я не устанавливаю положение полосы прокрутки, просто перемещаю весь контейнер сообщений вверх. Так что, какой бы ни была ваша позиция прокрутки, она останется прежней. По крайней мере, вниз, конечно, вы не сможете увидеть линии вверху.
Вы должны быть в состоянии настроить CSS для ваших нужд. Вы даже можете обойтись без JS, если будете использовать: фокус или немного другую настройку CSS, будьте креативны :)
источник
Вы должны добавить
document.querySelector(".messages").scrollTop = 10000;
вtest
функцию, когда добавляете маржу, затемscrollTop
заканчиваете загрузку, которую вы установили,scrolltop
и когда вы добавляете маржу или удаляете маржуscrolltop
, не установленную снова, измените ваш скрипт так, как этоисточник
Кажется, есть проблема с функцией переключения js. Я изменил это на простой прятки. Также я добавил ширину тега ввода. Вам также нужно добавить позицию: абсолютное в div-сообщения send и bottom: 0, чтобы оно оставалось внизу. затем поместите position: относительный в контейнер так, чтобы div отправляющего сообщения оставался в контейнере. Это означает, что контейнер сообщений не будет влиять на сами сообщения и поднимать их.
источник
Чисто несовершенный подход CSS, который я могу придумать, заключается в следующем:
Верхний раздел имеет небольшую проблему, когда есть поле. Хитрость здесь в том, чтобы использовать отрицательное поле и использовать translate для «прокрутки вверх» (на самом деле не прокрутки, а иллюзии)
wrapper
div.источник
div
)?К нему можно очень просто обратиться с помощью имен якоря. Посмотрите на скрипку JS на https://jsfiddle.net/gvbz93sx/
HTML Change
<a name="bottom"></a>
JS Change
document.location.hash = "#bottom";
источник