Прокрутіть донизу діва?


807

Я створюю чат, використовуючи запити ajax у рейках, і я намагаюся отримати діва, щоб прокрутити донизу без особливої ​​удачі.

Я обгортаю все в цьому розділі:

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

Чи є спосіб затримати його за промовчанням донизу за допомогою JS?

Чи є спосіб зберегти його прокручувати донизу після запиту на ajax?

Відповіді:


1324

Ось що я використовую на своєму сайті:

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

13
це метод добре з усіма браузерами?
jondinham

1
@PaulDinh: Я щойно вивчив це, і є проблема з IE7 і нижче за допомогою scrollHeight. Там , здається, робота навколо для IE7 тут .
Шон

2
Чому це не працює після динамічно додавання елементів всередині div?
Вінс

3
@Vince - це разова угода. Якщо ви зміните вміст, вам потрібно буде повторно виконати. Команда в основному говорить "перемістіть смугу прокрутки до цього положення".
DrFriedParts

8
А крім того, якщо у вас, наприклад, елементи розміщені всередині діла, ви можете прокрутити певний елемент у подання. (тобто елемент видно всередині батьківського div) .. ось так: $ ("#" + instanceID) .scrollTop ($ ("#" + instanceID) [0] .scrollIntoView);
netfed

360

Це набагато простіше, якщо ви використовуєте jQuery scrollTop :

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

272
Як це легше?
капітани

78
1 рядок замість 2? немає ніякого поняття, але те, що ви можете легко зробити з JQuery, це анімувати дію так: $ ("# div-id"). animete ({scrollTop: $ ("# div-id") [0] .scrollHeight}, 1000 ); сподіваюся, що це допоможе комусь :)
Самуїл

28
вам потрібно [0], щоб отримати елемент dom від елемента jquery, щоб отримати scrollHeight
Jimmy Bosse

14
"Не кажучи вже про JQ важче читати / розуміти!" Чисто думка. Я, наприклад, вважаю, що JQuery набагато простіше читати, розуміти та робити щось із цим. І це рішення НАЙКРАЩЕ, якщо ви вже використовуєте JQuery.
Ганна

47
Не повторюючи себе:$("#mydiv").scrollTop(function() { return this.scrollHeight; });
Ерік,

98

Ви можете використовувати наступний код:

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


92

використовуючи анімацію jQuery :

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

5
Ось що Сем сказав у цьому коментарі . Це, мабуть, корисніше в реальній відповіді!
Квентін Прадет

6
Зверніть увагу, як використовується ця відповідь .stop () , яка запобігає виникненню проблем із кількома анімаціями.
калифе

Дивно, але це єдиний, хто працює для мене з усіх відповідей раніше. Це може бути через те, як інші мої диви встановлені навколо шару, який повинен продовжувати прокручування
Дюніад

Це був єдиний, хто працював на мене (я додаю зображення, а не текст)
John ktejik


31

Новіший метод, який працює у всіх поточних браузерах :

this.scrollIntoView(false);

1
Думаю, що це працює лише у firefox: developer.mozilla.org/en/docs/Web/API/Element/…
Амріт Калон

3
Підтримки дійсно не вистачає атм, але якщо це буде прийнято, то це було б приголомшливо.
Kristjan Liiva

Будь які оновлення? Я вважаю, що це слід сприймати як хорошу відповідь. Я маю на увазі прийти на jQuery?
lkahtz

працює: document.querySelector (". mdl-list"). scrollIntoView (false);
Йоган Медіна

15

плавне прокручування за допомогою Javascript:

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


8

Якщо ви не хочете покладатися на це scrollHeight, допоможе наступний код:

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

1
Жодне з перерахованих вище рішень, включаючи ваше, здається, не працює на Firefox на Android ... будь-які думки, будь ласка?
Тост Кая

Неважливо, я використовував занадто велику кількість ( 1E10). Менша кількість робіт
andrewtweber

Це завжди має значення
Бен Таліадорос

4
Чому це було б поганою роботою? Це не так, як він повторюється над кожним пікселем. Тепер погана практика - це ще одне питання ...
devios1

$ ('# scroll'). scrollTop (Нескінченність), це також має працювати тоді.
Мадхав Поудель

5

Використовуючи 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);

4

Я зіткнувся з тією ж проблемою, але з додатковим обмеженням: я не мав контролю над кодом, який додав нові елементи до контейнера прокрутки. Жоден із знайдених тут прикладів не дозволив мені зробити саме це. Ось рішення, з яким я закінчився.

Він використовує 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 є змінною. Як я можу отримати доступ до цього ідентифікатора в скрипті.
Ірфан Юзаніф

Я не зовсім впевнений, що розумію ваше запитання. У моєму прикладі "myId" - це ідентифікатор контейнера прокрутки. Ви хочете створити більше однієї області, де користувач може прокручувати?
Benkinass

4

Javascript або jquery:

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

Css:

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

4

Знайшов це справді корисним, дякую.

Для кутових 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 стає трохи плутаним з кутовими.

Також для програми чату, я вважаю, що виконання цього завдання після завантаження ваших чатів буде корисним, вам також може знадобитися ляпати за короткий час.


3

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

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;

3

Так само як бонусний фрагмент. Я використовую кутовий і намагався прокрутити нитку повідомлень донизу, коли користувач вибирав різні розмови з користувачами. Для того щоб переконатися, що прокрутка працює після завантаження нових даних у діву з ng-повтором для повідомлень, просто загортайте фрагмент прокрутки в тайм-аут.

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

Це дозволить переконатися, що подія прокрутки буде запущена після того, як дані були вставлені в DOM.


Я підозрюю, що $ range. $ Apply (зворотний виклик) спрацює так само, як це змушує переварити та переоцінити думку.
SStanley

Дякую! Мені справді було цікаво, чому я не можу змусити його працювати і $ timeout було проблемою.
Wayferer

@Wayferer samesetTimeout(function() { ... }, n)
KingRider

3

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

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

що призведе до плавного прокручування до вершини діва з id "div-id".


3

Сценарій Java:

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

Прокручується до останнього рядка присутнього вмісту.


2

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

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

1

Дуже простий метод для цього - встановити scroll toвисоту діва.

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

1

Перейдіть до останнього елемента всередині div:

myDiv.scrollTop = myDiv.lastChild.offsetTop

1

У моїй програмі Angular 6 я тільки що зробив це:

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

Функція clearInterval (інтервал) зупинить таймер, щоб дозволити ручну прокрутку зверху / знизу.


1

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

Я спробував відповідь @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


-1

Я знаю, що це давнє питання, але жодне з цих рішень для мене не вийшло. Я в кінцевому підсумку використовував офсет () .горі, щоб отримати бажані результати. Ось що я акуратно прокручував екран до останнього повідомлення в моїй програмі чату:

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

Я сподіваюся, що це допомагає комусь іншому.


-1

Іноді найпростішим є найкраще рішення: я не знаю, чи допоможе це, це допомогло мені прокрутити його, коли я теж хотів. Чим вище "y =", тим більше вниз воно прокручується, і, звичайно, "0" означає верх, тому, наприклад, "1000" може бути внизу, або "2000" або "3000" і так далі, залежно від того, скільки триває сторінка є. Зазвичай це працює у кнопці з onclick або onmouseover.

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

-1

Встановіть відстань від верху прокручуваного елемента таким чином, щоб було загальною висотою елемента.

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

Не додайте те саме рішення, якщо воно вже існує.
Асон

так, не робіть цього, якщо рішення вже існує
Освальдо

-1

Ви можете використовувати метод HTML DOM scrollIntoView таким чином:

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

-2

використання:

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 = елемент [0] .scrollHeight - element.outerHeight ();
Махді Багері

-2

Якщо це робиться для прокрутки до нижньої частини вікна чату, зробіть наступне

Ідея прокрутки до конкретного дива у чаті була така

1) Кожен роздільник чату, що складається з особи, часу та повідомлення, виконується у циклі for для класу chatContentbox

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

3) перейти до останнього

4) scrollIntoView ()

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

Уже дано кілька відповідей scrollIntoView, тому немає потреби додавати ще одну.
Асон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.