2012-03-23 34 views
22

Tôi có một trang hiển thị các thông báo và tôi muốn nó hoạt động giống như Facebook, nhưng không có bộ tải lười. Tin nhắn được hiển thị theo thứ tự thời gian, gần đây nhất.jquery - giữ cửa sổ thay đổi vị trí cuộn trong khi thêm các mục vào danh sách?

Danh sách thư của tôi ban đầu được điền số x thư gần đây nhất và cửa sổ được cuộn xuống dưới cùng. Khi người dùng bắt đầu đọc chủ đề, họ đọc từ dưới lên trên. Nếu họ lên tới đỉnh, họ có thể tải thêm tin nhắn ... Tôi làm cho họ bấm vào một nút ... facebook có bộ nạp lười. Thư mới được thêm vào danh sách.

Sự cố: Khi thư mới được thêm vào trước, thư hiện có bị đẩy xuống, khiến người dùng mất địa điểm "đang xem" của họ. Làm cách nào để giữ vị trí hiện tại của người dùng khi tôi thêm các tin nhắn mới? Ví dụ, mở một chuỗi tin nhắn dài trong facebook, cuộn lên trên cùng để thêm các tin nhắn mới ... vị trí xem của bạn không thay đổi mặc dù vị trí cuộn có.

Trả lời

41

Lưu trữ một tham chiếu đến thông điệp đầu tiên trước khi bạn thêm vào trước tin nhắn mới, và sau khi bạn bổ sung, thiết lập các cuộn để bù đắp của thông điệp rằng:

$(document).on('scroll', function() { 
    var scroll = $(document).scrollTop(); 
    if (scroll < 1) { 
     // Store eference to first message 
     var firstMsg = $('.message:first'); 

     // Prepend new message here (I'm just cloning...) 
     $('body').prepend(firstMsg.clone()); 

     // After adding new message(s), set scroll to position of 
     // what was the first message 
     $(document).scrollTop(firstMsg.offset().top); 
    } 
}); 

Demo: http://jsfiddle.net/GRnQY/

Sửa: Tôi nhận thấy bạn muốn nó với một nút. Bạn có thể phải làm một chút toán học hơn:

$(document).on('click', '#loadMore', function() { 
    var firstMsg = $('.message:first'); 

    // Where the page is currently: 
    var curOffset = firstMsg.offset().top - $(document).scrollTop(); 

    // Prepend 
    firstMsg.before(firstMsg.clone()); 

    // Offset to previous first message minus original offset/scroll 
    $(document).scrollTop(firstMsg.offset().top-curOffset); 
}); 

Demo: http://jsfiddle.net/GRnQY/5/

+6

Giải pháp thứ hai là AWESOME - cảm ơn bạn rất nhiều, điều này rất hữu ích khi triển khai "cuộn vô hạn ngược" một tin nhắn trên Facebook. –

+0

Nếu bạn đang sử dụng ajax, hãy thêm '$ (selector) .scrollTop (firstMsg.offset(). Top-curOffset);' trên thuộc tính ajax 'success' để cuộn hoạt động đúng – user3284463

+0

Tuyệt vời! Cảm ơn Jeff! – Can

5

Không cần jQuery ở đây, chỉ cần kiểm tra những thay đổi trong các yếu tố scrollHeight và điều chỉnh scrollTop cho phù hợp, ví dụ:

var lastScrollHeight = el.scrollHeight; 
for(var n=0; n<10; n++){ 
    // Prepend here... 
} 
var scrollDiff = el.scrollHeight - lastScrollHeight; 
el.scrollTop += scrollDiff; 

Demo

http://jsfiddle.net/fkqqv28e/

jQuery

Để truy cập nút DOM gốc từ bộ sưu tập jQuery, hãy sử dụng truy cập mảng; tức là:

var lastScrollHeight = $('#myElement')[0].scrollHeight; 
for(var n=0; n<10; n++){ 
    $('#myElement').prepend('<div>prepended '+Math.random()+'</div>'); 
} 
var scrollDiff = $('#myElement')[0].scrollHeight - lastScrollHeight; 
$('#myElement')[0].scrollTop += scrollDiff; 
0

Tôi vừa chạy qua một biến thể của điều này. tôi tách ra một số lượng lớn các yếu tố, xử lý chúng và sau đó gắn chúng lại. điều này không hoàn thành đồng bộ trong Chrome nên tôi không thể đặt $ el.scrollTop (oldval) đáng tin cậy. Tôi tìm thấy giải pháp này làm việc cho tôi.

// get old scroll top of '#sub_elem' 
oldScrollTop = $('#sub_elem).scrollTop(); 

// detach 
$els = $('#sub_elem').detach(); 

// complex processing on #sub_elem 
// goes here 

// attach 
$('#main_el').attach($els); 

// problem- always scrolls #sub_elem back to the top 
// attempt #1: $('#sub_elem').scrollTop(oldScrollTop); // fails on mac Chrome 
// attempt #2: use instant animation. this works on mac Chrome 
if (oldScrollTop) { 
    $('#sub_elem').animate({ 
     scrollTop: oldScrollTop 
    }, 0); 
} 
1

Một số người đến đây chỉ có thể muốn thêm nội dung mà không có trọng tâm hiện tại nhảy xung quanh. Sửa đổi bản demo của Jeff B ở trên để sử dụng mục tiêu sự kiện nhấp chuột làm cho thành ngữ này trở nên dễ dàng hơn:

someButton.on('click', function() { 
    var curOffset = $(this).offset().top - $(document).scrollTop(); 
    // add content to your heart's content. 
    $(document).scrollTop($(this).offset().top-curOffset); 
}); 

c.f. http://jsfiddle.net/bwz8uLvt/1/ (biến thể của bản demo của Jeff B ở trên nhưng với nút [thêm chi tiết] tại một điểm tùy ý trong trang).

0

Bạn cũng có thể giữ vị trí cuộn dựa trên độ lệch ở cuối trang/phần tử.

var ScrollFromBottom = $(document).height() - $(window).scrollTop(); 

//ajax - add messages -- geenrate html code then add to dom 

//set scroll position 
$(window).scrollTop($(document).height() - ScrollFromBottom); 
Các vấn đề liên quan