Прокрутка переполненных DIV с помощью JavaScript

У меня есть div, который использует overflow: auto, чтобы сохранить содержимое внутри div при изменении размера и перетаскивании по странице. Я использую некоторый ajax для получения строк текста с сервера, а затем добавляю их в конец div, чтобы содержимое увеличивалось вниз. Каждый раз, когда это происходит, я хотел бы использовать JS для прокрутки div вниз, чтобы был виден последний добавленный контент, аналогично тому, как работает комната чата или консоль командной строки.

До сих пор я использовал этот фрагмент для этого (я также использую jQuery, отсюда и функцию $ ()):

$("#thediv").scrollTop = $("#thediv").scrollHeight;

Однако это давало мне противоречивые результаты. Иногда это работает, иногда нет, и он полностью перестает работать, если пользователь когда-либо изменяет размер div или перемещает полосу прокрутки вручную.

Целевым браузером является Firefox 3, и он развертывается в контролируемой среде, поэтому ему вообще не нужно работать в IE.

Есть идеи, ребята? Это поставило меня в тупик. Спасибо!

Ответов (6)

Решение

scrollHeight должна быть общая высота содержимого. scrollTop задает смещение в пикселях в этом содержимом, которое будет отображаться в верхней части клиентской области элемента.

Итак, вы действительно хотите (все еще используете jQuery):

$("#thediv").each( function() 
{
   // certain browsers have a bug such that scrollHeight is too small
   // when content does not fill the client area of the element
   var scrollHeight = Math.max(this.scrollHeight, this.clientHeight);
   this.scrollTop = scrollHeight - this.clientHeight;
});

... который установит смещение прокрутки до последнего clientHeight значения содержимого.

scrollIntoView

Метод scrollIntoView прокручивает элемент в поле зрения.

У меня был div, оборачивающий 3 div, плавающих влево, и размер содержимого которых менялся. Когда вы пытаетесь решить эту проблему, это помогает включить границы / фон фанк-цвета для div-оболочки. Проблема заключалась в том, что содержимое div с измененным размером переполнялось за пределами оболочки div (и кровоточило под областью содержимого под оболочкой).

Решено с помощью ответа @ Shog9 выше. Применительно к моей ситуации это был макет HTML:

<div id="div-wrapper">
  <div class="left-div"></div>
  <div id="div-content" class="middle-div">
  Some short/sweet content that will be elongated by Jquery.
  </div>
  <div class="right-div"></div>
</div>

Это был мой jQuery для изменения размера обертки div:

<script>
$("#div-content").text("a very long string of text that will overflow beyond the width/height of the div-content");
//now I need to resize the div...
var contentHeight = $('#div-content').prop('scrollHeight')
$("#div-wrapper").height(contentHeight);
</script>

Отметим, что $ ('# div-content'). Prop ('scrollHeight') задает высоту, до которой оболочка должна изменить размер. Также мне неизвестен какой-либо другой способ получить scrollHeight фактическую функцию jQuery; Ни один из $ ('# div-content'). ScrollTop () и $ ('# div-content'). Height не даст реальных значений высоты содержимого. Надеюсь, это кому-то поможет!

Это можно сделать на простом JS. Хитрость заключается в том, чтобы установить scrollTop на значение, равное или превышающее общую высоту элемента ( scrollHeight ):

const theDiv = document.querySelector('#thediv');
theDiv.scrollTop = Math.pow(10, 10);

Из MDN :

Если установлено значение, превышающее максимальное, доступное для элемента, scrollTop устанавливает максимальное значение.

В то время как значение сработало, Math.pow(10, 10) используя слишком высокое значение, например Infintiyили Number.MAX_VALUE, сбросит scrollTop на 0 (Firefox 66).

Использование цикла для перебора jQuery, состоящего из одного элемента, довольно неэффективно. При выборе идентификатора вы можете просто получить первый и уникальный элемент jQuery с помощью функции get () или записи [].

var div = $("#thediv")[0];

// certain browsers have a bug such that scrollHeight is too small
// when content does not fill the client area of the element
var scrollHeight = Math.max(div.scrollHeight, div.clientHeight);
div.scrollTop = scrollHeight - div.clientHeight;
$("#thediv").scrollTop($("#thediv")[0].scrollHeight);