Прокрутить до конца div?

Я создаю чат, используя запросы Ajax, и без особого успеха пытаюсь заставить div сообщений прокручиваться вниз.

Я оборачиваю все в этот div:

#scroll {
    height:400px;
    overflow:scroll;
}

Есть ли способ по умолчанию прокручивать его вниз с помощью JS?

Есть ли способ сохранить его прокруткой вниз после запроса ajax?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
898
0
891 268
31
Перейти к ответу Данный вопрос помечен как решенный

Ответы 31

Ответ принят как подходящий

Вот что я использую на своем сайте:

var objDiv = document.getElementById("your_div");
objDiv.scrollTop = objDiv.scrollHeight;

подходит ли этот метод для всех браузеров?

jondinham 02.03.2012 14:35

@PaulDinh: Я только что изучил это, и есть проблема с IE7 и ниже, используя scrollHeight. Кажется, есть обходной путь для IE7 здесь.

Sean 18.08.2012 20:44

почему бы не scrollTopMax вместо scrollHeight?

aiven 23.09.2018 23:09

Это не работает, когда я динамически добавляю изображения :(

john ktejik 16.04.2019 05:54

«Современный» способ - использовать Element.scrollIntoView () - developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoV‌ iew

MichielB 14.08.2020 18:27

можете ли вы использовать var element = document.getElementById ("elementToSelect"); element.scrollIntoView ();

Lucas Breitembach 30.09.2020 00:24

Это не сработало для меня. Если у вас есть запрос, используйте @andsien .. Обратите внимание, что альтернативный анимированный вариант может иметь неотредактированное поведение с блокировкой полосы прокрутки в Safari <= 14.0.1 (последняя версия)

Tyler Miles 20.12.2020 02:35

Это намного проще, если вы используете jQuery scrollTop:

$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);

вам нужно [0], чтобы получить элемент dom из элемента jquery, чтобы получить scrollHeight

Jimmy Bosse 16.07.2012 02:18

Без повторения: $("#mydiv").scrollTop(function() { return this.scrollHeight; });

Eric 23.03.2014 23:44

используя jQuery animate:

$('#DebugContainer').stop().animate({
  scrollTop: $('#DebugContainer')[0].scrollHeight
}, 800);

Обратите внимание, как в этом ответе используется .останавливаться(), который предотвращает проблемы с несколькими анимациями.

kalyfe 20.08.2013 12:29
var mydiv = $("#scroll");
mydiv.scrollTop(mydiv.prop("scrollHeight"));

Работает с jQuery 1.6

https://api.jquery.com/scrollTop/

http://api.jquery.com/prop/

Если вы не хотите полагаться на scrollHeight, вам поможет следующий код:

$('#scroll').scrollTop(1000000);

похоже на взлом. что означает число 1000000?

Evgeniy Boytsov 20.11.2020 13:15

небольшое дополнение: прокручивается, только если последняя строка уже видна. если прокрутить немного, оставляет содержимое там, где оно есть (внимание: не тестировалось с разными размерами шрифта. Это может потребовать некоторых корректировок внутри "> = сравнение"):

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;

Просто как бонусный фрагмент. Я использую angular и пытался прокрутить цепочку сообщений вниз, когда пользователь выбирал разные разговоры с пользователями. Чтобы убедиться, что прокрутка работает после того, как новые данные были загружены в div с помощью ng-repeat для сообщений, просто оберните фрагмент прокрутки в тайм-аут.

$timeout(function(){
    var messageThread = document.getElementById('message-thread-div-id');
    messageThread.scrollTop = messageThread.scrollHeight;
},0)

Это гарантирует, что событие прокрутки запускается после того, как данные были вставлены в DOM.

Я подозреваю, что $ scope. $ Apply (обратный вызов) будет работать так же хорошо, как это заставит дайджест и переоценку представления.

SStanley 17.08.2016 08:46

Спасибо! Мне действительно было интересно, почему я не могу заставить его работать, и проблема заключалась в тайм-ауте $.

Wayferer 03.07.2018 07:49

@Wayferer тот же setTimeout(function() { ... }, n)

KingRider 01.11.2019 20:45

Более новый метод, который работает на все текущие браузеры:

this.scrollIntoView(false);

Это должен быть принятый ответ, поскольку старые методы больше не работают.

rbansal 13.09.2020 18:27

Это было бы так, если бы "this" - это что-то в div, которое можно прокрутить до

mplungjan 24.09.2020 10:20

Метод scrollIntoView запускается для дочернего элемента внутри родительского контейнера. Итак, как использовать его, чтобы: прокрутить родителя вниз (как задано в исходном вопросе).

Gil Epshtain 08.02.2021 19:43

Можно использовать scrollIntoView({ behavior: "smooth", block: "end" });

giovannipds 19.02.2021 23:30

Посмотрите, какие браузеры здесь поддерживаются caniuse.com/?search=scrollIntoView

Akira Yamamoto 24.02.2021 03:40

Используя jQuery, scrollTop используется для установки вертикального положения полосы прокрутки для любого заданного элемента. есть также красивый плагин jquery scrollTo, используемый для прокрутки с анимацией и различными параметрами (демонстрации)

var myDiv = $("#div_id").get(0);
myDiv.scrollTop = myDiv.scrollHeight;

если вы хотите использовать Метод анимации jQuery для добавления анимации при прокрутке вниз, проверьте следующий фрагмент:

var myDiv = $("#div_id").get(0);
myDiv.animate({
    scrollTop: myDiv.scrollHeight
  }, 500);

Это позволит вам прокручивать страницу вниз по высоте документа.

$('html, body').animate({scrollTop:$(document).height()}, 1000);

Нашел это действительно полезным, спасибо.

Для разработчиков 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;

  }
]);

Просто потому, что упаковка элементов jQuery по сравнению с элементами HTML DOM немного сбивает с толку с angular.

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

Я столкнулся с той же проблемой, но с дополнительным ограничением: у меня не было контроля над кодом, добавляющим новые элементы в контейнер прокрутки. Ни один из примеров, которые я здесь нашел, не позволял мне этого делать. Вот решение, к которому я пришел.

Он использует Mutation Observers (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver), что позволяет использовать его только в современных браузерах (хотя полифиллы существуют)

Итак, в основном код делает именно это:

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});

Я сделал скрипку, чтобы продемонстрировать концепцию: https://jsfiddle.net/j17r4bnk/

как получить динамический идентификатор? как в <div class = "abc"><div data-bind=attr : {'id': myId } ></div></div> В этом коде myId - это переменная. Как я могу получить доступ к этому идентификатору в скрипте.

Irfan Yusanif 09.10.2015 10:20

Я не совсем уверен, что понимаю ваш вопрос. В моем примере «myId» - это идентификатор контейнера прокрутки. Вы хотите создать более одной области, в которой пользователь может прокручивать?

Benkinass 12.10.2015 10:33

Вы можете попробовать приведенный ниже код:

function scrollToBottom (id) {
   var div = document.getElementById(id);
   div.scrollTop = div.scrollHeight - div.clientHeight;
}

Чтобы выполнить прокрутку гладкий с помощью JQuery:

function scrollSmoothToBottom (id) {
   var div = document.getElementById(id);
   $('#' + id).animate({
      scrollTop: div.scrollHeight - div.clientHeight
   }, 500);
}

См. пример на JSFiddle

Вот почему это работает:

Ссылка: scrollTop, scrollHeight, clientHeight

это действительно правильный ответ, картинка действительно полезна

defend orca 28.09.2020 16:41

Вы также можете, используя jQuery, прикрепить анимацию к html,body документа через:

$("html,body").animate({scrollTop:$("#div-id")[0].offsetTop}, 1000);

что приведет к плавной прокрутке вверху div с идентификатором «div-id».

Javascript или jquery:

var scroll = document.getElementById('messages');
   scroll.scrollTop = scroll.scrollHeight;
   scroll.animate({scrollTop: scroll.scrollHeight});

CSS:

 .messages
 {
      height: 100%;
      overflow: auto;
  }

Я знаю, что это старый вопрос, но ни одно из этих решений для меня не помогло. В итоге я использовал offset (). Top для получения желаемых результатов. Вот что я использовал для мягкого прокрутите экран вниз последнего сообщения в моем приложении чата:

$("#html, body").stop().animate({
     scrollTop: $("#last-message").offset().top
}, 2000);

Надеюсь, это поможет кому-то другому.

Javascript:

document.getElementById('messages').scrollIntoView(false);

Прокручивает до последней строки присутствующего содержимого.

Очень простой способ - установить scroll to на высоту div.

var myDiv = document.getElementById("myDiv");
window.scrollTo(0, myDiv.innerHeight);

Прокрутите до последнего элемента внутри div:

myDiv.scrollTop = myDiv.lastChild.offsetTop

гладкий прокрутка с помощью Javascript:

document.getElementById('messages').scrollIntoView({ behavior: 'smooth', block: 'end' });

использовать :

var element= $('element');
var maxScrollTop = element[0].scrollHeight - element.outerHeight();
element.scrollTop(maxScrollTop);

или проверьте прокрутку вниз:

    var element = $(element);
    var maxScrollTop = element[0].scrollHeight - element.outerHeight();
    element.on('scroll', function() {
        if ( element.scrollTop() >= maxScrollTop ) {
            alert('scroll to bottom');
        }
    });

измените scrollTopMax на var maxScrollTop = element [0] .scrollHeight - element.outerHeight ();

Mahdi Bagheri 10.07.2019 14:50

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

Идея прокрутки к конкретному div в чате заключалась в следующем

1) Каждый div чата, состоящий из Person, time и message, запускается в цикле for с классом chatContentbox.

2) querySelectorAll находит все такие массивы. Это может быть 400 узлов (400 чатов)

3) перейти к последнему

4) scrollIntoView ()

let lastChatBox = document.querySelectorAll('.chatContentBox'); 
lastChatBox = lastChatBox[lastChatBox.length-1]; 
lastChatBox.scrollIntoView(); 

Иногда самое простое - лучшее решение: Я не знаю, поможет ли это, мне тоже помогло прокрутить его, когда я когда-либо хотел. Чем выше "y =", тем больше он прокручивается вниз, и, конечно же, "0" означает верх, поэтому, например, "1000" может быть низом, или "2000", или "3000" и так далее, в зависимости от того, как долго вы страница есть. Обычно это работает в кнопке с onclick или onmouseover.

window.scrollTo(x=0,y=150);

Установите расстояние от верха прокручиваемого элемента как общую высоту элемента.

const element = this.shadowRoot.getElementById('my-scrollable-div')
element.scrollTop = element.scrollHeight

В моем приложении Angular 6 я только что сделал это:

postMessage() {
  // post functions here
  let history = document.getElementById('history')
  let interval    
  interval = setInterval(function() {
    history.scrollTop = history.scrollHeight
    clearInterval(interval)
  }, 1)
}

Функция clearInterval (interval) остановит таймер, чтобы разрешить ручную прокрутку вверх / вниз.

Вы можете использовать метод scrollIntoView HTML DOM следующим образом:

var element = document.getElementById("scroll");
element.scrollIntoView();

Мой сценарий: у меня был список строк, в который мне нужно было добавить строку, заданную пользователем, и автоматически прокрутить до конца списка. У меня была фиксированная высота отображения списка, после чего он должен переполняться.

Я попробовал ответить @Jeremy Ruten, он сработал, но прокручивался до (n-1) -го элемента. Если кто-то сталкивается с этой проблемой, вы можете использовать обходной путь метода setTimeOut(). Вам необходимо изменить код, как показано ниже:

setTimeout(() => {
    var objDiv = document.getElementById('div_id');
    objDiv.scrollTop = objDiv.scrollHeight
}, 0)

Вот созданная мной ссылка на StcakBlitz, которая показывает проблему и ее решение: https://stackblitz.com/edit/angular-ivy-x9esw8

с setTimeout () все работает нормально. Работал с angular 9. День спас.

Anjali Sharma 13.10.2020 14:07

Рад помочь :)

ngShravil.py 14.10.2020 16:30

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

//get the div that contains all the messages
let div = document.getElementById('message-container');

//make the last element (a message) to scroll into view, smoothly!
div.lastElementChild.scrollIntoView({ behavior: 'smooth' });

Я использую разницу между координатой Y первого элемента div и координатой Y выбранного элемента div. Вот код JavaScript / JQuery и HTML:

function scrollTo(event){
        // In my proof of concept, I had a few <button>s with value 
        // attributes containing strings with id selector expressions
        // like "#item1".
        let selectItem = $($(event.target).attr('value'));
        let selectedDivTop = selectItem.offset().top;

        let scrollingDiv = selectItem.parent();

        let firstItem = scrollingDiv.children('div').first();
        let firstItemTop = firstItem.offset().top;

        let newScrollValue = selectedDivTop - firstItemTop;
        scrollingDiv.scrollTop(newScrollValue);
    }
<div id = "scrolling" style = "height: 2rem; overflow-y: scroll">
  <div id = "item1">One</div>
  <div id = "item2">Two</div>
  <div id = "item3">Three</div>
  <div id = "item4">Four</div>
  <div id = "item5">Five</div>
</div>

Вы можете использовать метод Элемент.scrollTo ().

Его можно анимировать с помощью встроенной анимации браузера / ОС, поэтому он очень плавный.

function scrollToBottom() {
    const scrollContainer = document.getElementById('container');
    scrollContainer.scrollTo({
        top: scrollContainer.scrollHeight,
        left: 0,
        behavior: 'smooth'
    });
}

// initialize dummy content
const scrollContainer = document.getElementById('container');
const numCards = 100;
let contentInnerHtml = '';
for (let i=0; i<numCards; i++) {
  contentInnerHtml += `<div class = "card mb-2"><div class = "card-body">Card ${i + 1}</div></div>`;
}
scrollContainer.innerHTML = contentInnerHtml;
.overflow-y-scroll {
  overflow-y: scroll;
}
<link href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel = "stylesheet"/>

<div class = "d-flex flex-column vh-100">
  <div id = "container" class = "overflow-y-scroll flex-grow-1"></div>
  <div>
    <button class = "btn btn-primary" onclick = "scrollToBottom()">Scroll to bottom</button>
  </div>
</div>

альтернативное решение

function scrollToBottom(element) {
  element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
}

Другие вопросы по теме