Cuộn xuống dưới cùng của div?


808

Tôi đang tạo một cuộc trò chuyện bằng cách sử dụng các yêu cầu ajax trong đường ray và tôi đang cố gắng để một div di chuyển xuống phía dưới mà không gặp nhiều may mắn.

Tôi đang gói mọi thứ trong div này:

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

Có cách nào để giữ cho nó được cuộn xuống phía dưới theo mặc định bằng cách sử dụng JS không?

Có cách nào để giữ cho nó cuộn xuống phía dưới sau khi yêu cầu ajax không?

Câu trả lời:


1325

Đây là những gì tôi sử dụng trên trang web của mình:

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

13
Phương pháp này có ổn với tất cả các trình duyệt không?
jondinham

1
@PaulDinh: Tôi mới xem xét vấn đề này và có một vấn đề với IE7 và thấp hơn khi sử dụng scrollHeight. Dường như có một công việc xung quanh IE7 ở đây .
Sean

3
Tại sao nó không hoạt động sau khi bổ sung động các phần tử bên trong div?
Vince

3
@Vince - Đó là một thỏa thuận một lần. Nếu bạn thay đổi nội dung, bạn sẽ cần phải thực hiện lại. Lệnh về cơ bản nói "di chuyển thanh cuộn đến vị trí này".
DrFriedParts

8
Và ngoài ra, nếu bạn có các phần tử được đặt bên trong div chẳng hạn, bạn có thể cuộn một phần tử cụ thể vào dạng xem. (tức là phần tử hiển thị bên trong div cha) .. như thế này: $ ("#" + instanceID) .scrollTop ($ ("#" + instanceID) [0] .scrollIntoView);
netfed

360

Điều này dễ dàng hơn nhiều nếu bạn đang sử dụng jQuery scrollTop :

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

273
Làm thế nào là điều này dễ dàng hơn?
Captainspi

78
1 dòng thay vì 2? không có đầu mối, nhưng những gì bạn có thể làm dễ dàng với JQuery là hoạt hình hành động như vậy: $ ("# div-id"). animate ({scrollTop: $ ("# div-id") [0] .scrollHeight}, 1000 ); hy vọng điều này sẽ giúp được ai :)
Samuel

28
bạn cần [0] để lấy phần tử dom từ phần tử jquery để lấy scrollHeight
Jimmy Bosse

14
"Chưa kể JQ khó đọc / hiểu hơn!" Hoàn toàn là một ý kiến. Ví dụ, tôi thấy JQuery dễ đọc hơn, hiểu và làm mọi thứ với. Và giải pháp này tốt hơn nếu bạn đang sử dụng JQuery.
Hanna

47
Không lặp lại chính mình:$("#mydiv").scrollTop(function() { return this.scrollHeight; });
Eric

98

Bạn có thể sử dụng mã sau đây:

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

Để thực hiện cuộn trơn tru với JQuery:

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

Xem ví dụ trên JSFiddle

Đây là lý do tại sao điều này hoạt động:

nhập mô tả hình ảnh ở đây

Tham chiếu: scrollTop , scrollHeight , clientHeight


92

sử dụng jQuery animate :

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

5
Đó là những gì Sam nói trong bình luận này . Có lẽ nó hữu ích hơn trong một câu trả lời thực tế!
Quentin Pradet

6
Lưu ý cách câu trả lời này sử dụng .stop () , để ngăn sự cố với nhiều hình động.
kalyfe

Đáng ngạc nhiên đây là người duy nhất làm việc cho tôi trong số tất cả các câu trả lời trước đó. Có thể là do cách các div khác của tôi được thiết lập xung quanh lớp cần tiếp tục cuộn
Duniyadnd

Đây là người duy nhất làm việc cho tôi (Tôi đang thêm hình ảnh, không phải văn bản)
john ktejik


31

Phương pháp mới hơn hoạt động trên tất cả các trình duyệt hiện tại :

this.scrollIntoView(false);

1
Hãy nghĩ rằng điều này chỉ hoạt động trên firefox: developer.mozilla.org/en/docs/Web/API/Euity/
mẹo

3
Hỗ trợ thực sự thiếu atm, nhưng nếu điều này được chấp nhận, thì nó sẽ rất tuyệt vời.
Kristjan Liiva

Bất cứ cập nhật? Tôi cảm thấy điều này nên được chấp nhận là câu trả lời tốt. Ý tôi là đến với jQuery?
lkahtz

làm việc: document.querySelector (". mdl-list"). scrollIntoView (false);
Johann Medina

15

cuộn trơn tru với Javascript:

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


8

Nếu bạn không muốn dựa vào scrollHeight, đoạn mã sau sẽ giúp:

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

1
Không có giải pháp nào ở trên, kể cả của bạn, dường như hoạt động trên Firefox trên Android ... bạn có nghĩ gì không?
Bánh mì nướng Kaya

Đừng bận tâm, tôi đã sử dụng một số quá lớn ( 1E10). Một số lượng nhỏ hơn hoạt động
andrewtweber

Nó luôn luôn có vấn đề
Ben Taliadoros

4
Tại sao nó sẽ là hiệu suất xấu? Nó không giống như nó lặp đi lặp lại qua từng pixel. Bây giờ thực hành xấu là một câu hỏi khác
devios1

$ ('# scroll'). scrollTop (Infinity), điều này cũng sẽ hoạt động sau đó.
Madhav Poudel

5

Sử dụng jQuery, scrollTop được sử dụng để đặt vị trí dọc của scollbar cho bất kỳ phần tử nào. Ngoài ra còn có một plugin cuộn jquery đẹp được sử dụng để cuộn với hình động và các tùy chọn khác nhau ( bản demo )

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

nếu bạn muốn sử dụng phương thức hoạt hình của jQuery để thêm hình ảnh động trong khi cuộn xuống, hãy kiểm tra đoạn mã sau:

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

4

Tôi đã gặp phải vấn đề tương tự, nhưng với một ràng buộc bổ sung: Tôi không kiểm soát được mã đã gắn các phần tử mới vào thùng chứa cuộn. Không có ví dụ nào tôi tìm thấy ở đây cho phép tôi làm điều đó. Đây là giải pháp tôi đã kết thúc.

Nó sử dụng Mutation Observers( https://developer.mozilla.org/en-US/docs/Web/API/MutingObserver ) khiến nó chỉ có thể sử dụng được trên các trình duyệt hiện đại (mặc dù tồn tại polyfill)

Vì vậy, về cơ bản mã làm điều đó:

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

Tôi đã thực hiện một câu đố để thể hiện khái niệm: https://jsfiddle.net/j17r4bnk/


Làm thế nào để có được id động? như trong <div class="abc"><div data-bind=attr : {'id': myId } ></div></div>mã này myId là một biến. Làm thế nào tôi có thể truy cập id này trong kịch bản.
Irfan Yusanif

Tôi không chắc là tôi hiểu câu hỏi của bạn. Trong ví dụ của tôi, "myId" là id của thùng chứa cuộn. Bạn có muốn tạo nhiều hơn một khu vực nơi người dùng có thể cuộn không?
Benkinass

4

Javascript hoặc jquery:

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

Css:

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

4

Tìm thấy điều này thực sự hữu ích, cảm ơn bạn.

Đối với những người Angular 1.X ngoài kia:

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;

  }
]);

Chỉ vì việc gói các phần tử jQuery so với các phần tử DOM DOM có một chút khó hiểu với góc cạnh.

Ngoài ra, đối với một ứng dụng trò chuyện, tôi thấy việc thực hiện nhiệm vụ này sau khi các cuộc trò chuyện của bạn được tải là hữu ích, bạn cũng có thể cần phải tát vào thời gian chờ ngắn.


3

phụ lục nhỏ: chỉ cuộn, nếu dòng cuối cùng đã hiển thị. nếu cuộn một chút, hãy để lại nội dung (chú ý: không được kiểm tra với các kích thước phông chữ khác nhau. Điều này có thể cần một số điều chỉnh bên trong "> = so sánh"):

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

Cũng như một đoạn thưởng. Tôi đang sử dụng góc cạnh và đang cố cuộn một chuỗi tin nhắn xuống phía dưới khi người dùng chọn các cuộc hội thoại khác nhau với người dùng. Để đảm bảo rằng cuộn hoạt động sau khi dữ liệu mới đã được tải vào div với ng-repeat cho các tin nhắn, chỉ cần bọc đoạn mã cuộn trong thời gian chờ.

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

Điều đó sẽ đảm bảo rằng sự kiện cuộn được kích hoạt sau khi dữ liệu được chèn vào DOM.


Tôi nghi ngờ $ scope. $ Áp dụng (gọi lại) sẽ hoạt động tốt vì điều này buộc phải phân loại và đánh giá lại quan điểm.
SStanley

Cảm ơn bạn! Tôi đã thực sự tự hỏi tại sao tôi không thể làm cho nó hoạt động và thời gian chờ là vấn đề.
Wayferer

@Wayferer cùngsetTimeout(function() { ... }, n)
KingRider

3

Bạn cũng có thể, bằng cách sử dụng jQuery, đính kèm một hình ảnh động vào html,bodytài liệu thông qua:

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

Điều này sẽ dẫn đến một cuộn trơn tru lên đầu div với id "div-id".


3

Tập lệnh Java:

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

Cuộn đến dòng cuối cùng của nội dung hiện tại.


2

Điều này sẽ cho phép bạn cuộn xuống hết cỡ liên quan đến chiều cao tài liệu

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

1

Một phương pháp rất đơn giản để làm điều này là đặt scroll tochiều cao của div.

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

1

Cuộn đến phần tử cuối cùng bên trong div:

myDiv.scrollTop = myDiv.lastChild.offsetTop

1

Trên ứng dụng Angular 6 của tôi, tôi đã làm điều này:

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

Hàm ClearInterval (distance) sẽ dừng bộ hẹn giờ để cho phép cuộn trên / dưới bằng tay.


1

Kịch bản của tôi: Tôi đã có một danh sách các chuỗi, trong đó tôi phải nối thêm một chuỗi do người dùng cung cấp và tự động cuộn đến cuối danh sách. Tôi đã cố định chiều cao của màn hình hiển thị danh sách, sau đó nó sẽ tràn ra.

Tôi đã thử câu trả lời của @Jeremy Ruten, nó đã hoạt động, nhưng nó đang cuộn đến phần tử thứ (n-1). Nếu bất cứ ai đang phải đối mặt với loại vấn đề này, bạn có thể sử dụng setTimeOut()phương pháp giải quyết. Bạn cần sửa đổi mã dưới đây:

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

Đây là liên kết StcakBlitz mà tôi đã tạo cho thấy vấn đề và giải pháp của nó: https://stackblitz.com/edit/angular-ivy-x9esw8


-1

Tôi biết đây là một câu hỏi cũ, nhưng không có giải pháp nào trong số này giải quyết được cho tôi. Tôi đã kết thúc bằng cách sử dụng offset (). Top để có kết quả mong muốn. Đây là những gì tôi đã sử dụng để nhẹ nhàng cuộn màn hình xuống tin nhắn cuối cùng trong ứng dụng trò chuyện của mình:

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

Tôi mong điều này giúp được người nào khác.


-1

Đôi khi, đơn giản nhất là giải pháp tốt nhất: Tôi không biết điều này có giúp ích gì không, nó giúp tôi cuộn nó bao giờ tôi cũng muốn. "Y =" càng cao, nó càng cuộn xuống và tất nhiên "0" có nghĩa là trên cùng, vì vậy, ví dụ "1000" có thể ở dưới cùng, hoặc "2000" hoặc "3000", v.v., tùy thuộc vào thời gian của bạn trang là. Điều này thường hoạt động trong một nút với onclick hoặc onmouseover.

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

-1

Đặt khoảng cách từ đỉnh của phần tử có thể cuộn là tổng chiều cao của phần tử.

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

Đừng thêm giải pháp tương tự nếu nó đã tồn tại.
Ason

vâng, đừng làm vậy nếu giải pháp đã tồn tại
Oswaldo

-1

Bạn có thể sử dụng Phương thức HTML DOM scrollIntoView như thế này:

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

-2

sử dụng :

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

hoặc kiểm tra cuộn xuống dưới cùng:

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

thay đổi scrollTopMax thành var maxScrollTop = phần tử [0] .scrollHeight - Element.outerHeight ();
Mahdi Bagheri

-2

Nếu điều này đang được thực hiện để cuộn xuống dưới cùng của cửa sổ trò chuyện, hãy làm như sau

Ý tưởng cuộn đến một div cụ thể trong cuộc trò chuyện là như sau

1) Mỗi ​​div trò chuyện bao gồm Người, thời gian và tin nhắn được chạy trong một vòng lặp for với lớp chatContentbox

2) querySelectorAll tìm thấy tất cả các mảng như vậy. Nó có thể là 400 nút (400 cuộc trò chuyện)

3) đi đến cái cuối cùng

4) scrollIntoView ()

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

Một số câu trả lời đã được đưa ra, bằng cách sử dụng scrollIntoView, vì vậy không cần thêm một câu trả lời nào nữa.
Ason
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.