Soru jquery - öğeleri bir listeye hazırlarken kaydırma pozisyonunu değiştirmekten kaçının.


Mesajları görüntüleyen bir sayfam var ve bunun sadece Facebook gibi çalışmasını istiyorum, ancak tembel yükleyici olmadan. Mesajlar kronolojik sırada en sonuncu sırada görüntülenir.

Mesaj listem başlangıçta en son gönderilen mesajların x sayısı ile doldurulur ve pencere en alta kaydırılır. Kullanıcı iş parçacığı okumaya başladığında, aşağıdan yukarıya doğru okur. Zirveye ulaşırlarsa daha fazla mesaj yükleyebilirler ... Onları bir butona tıklatırım ... facebook tembel bir yükleyiciye sahiptir. Yeni mesajlar listeye eklenir.

Sorun: Yeni mesajlar hazırlandıkça, mevcut mesajlar aşağı doğru itilerek kullanıcının "izleme" yerinin kaybolmasına neden oluyor. Yeni mesajları eklediğimde kullanıcının mevcut görünüm konumunu nasıl koruyabilirim? Örnek olarak, facebook'ta uzun bir mesaj dizisini açın, yeni mesajların eklenmesine neden olacak şekilde en üste kaydırın ... kaydırma pozisyonunda olsa bile görünüm konumunuz değişmez.


25
2018-03-23 04:22


Menşei




Cevaplar:


Yeni mesajlar göndermeden önce ilk mesaja bir referans kaydedin ve siz hazırladıktan sonra, kaydırmayı o mesajın ofsetine ayarlayın:

$(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/

Düzenle: Bir düğme ile istediğini fark ettim. Biraz daha matematik yapman gerekebilir:

$(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/


44
2018-03-23 04:40



İkinci çözüm AWESOME - çok teşekkür ederim, bu bir Facebook mesajları bir "ters sonsuz kaydırma" uygulamak için çok yararlı oldu. - Jacob Gillespie
Ajax kullanıyorsanız, ekleyin $(selector).scrollTop(firstMsg.offset().top-curOffset); ajax üzerinde success kaydırmanın düzgün çalışması için özellik - user3284463
Korku veren! Teşekkürler Jeff! - Can
Buraya gelen bazı kişiler muhtemelen sadece düğmeyi hareket ettirmeden bir düğmeyi tıklamak isteyeceklerdir. Bunun için hesaplamalar firstMsg.offset() Tıklama etkinliğinin hedef öğesini kullanarak bu parçacığı daha taşınabilir hale getirebilir: var curOffset = $(this).offset().top - $(document).scrollTop(); /* do stuff above the button */ $(document).scrollTop($(this).offset().top-curOffset);  Bakınız: <jsfiddle.net/bwz8uLvt/1/>; (demo üstünde ancak sayfada rastgele noktadaki düğmeyle) - ericP
senin 2. çözümün gerçekten harika! Teşekkürler, hala neden bu şekilde çalıştığını anlamaya çalışıyorum. - low_rents


Burada jQuery gerek yok, sadece öğeler scrollHeight değişiklikleri kontrol edin ve scrollTop buna göre ayarlayın, yani:

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

gösteri

http://jsfiddle.net/fkqqv28e/

jQuery

Bir jQuery koleksiyonundan yerel DOM düğümüne erişmek için dizi erişimini kullanın; yani:

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;

6
2017-11-25 14:15





Buraya gelen bazı milletler, yalnızca mevcut odakta gezinmeden içerik eklemek isteyebilir. Tıklama etkinliği hedefini kullanmak için yukarıdaki Jeff B's ​​demosunun değiştirilmesi, bu idiomun daha taşınabilir olmasını sağlar:

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

Bakınız: http://jsfiddle.net/bwz8uLvt/1/ (yukarıdaki Jeff B's'in demo versiyonu, ancak sayfadaki isteğe bağlı bir noktada [ekle] düğmesiyle).


2
2018-05-14 06:25





Sadece bunun bir çeşitliliğine rastladım. Çok sayıda elemanı ayırdım, işledim ve sonra tekrar ekledim. Bu, Chrome'da senkronize olarak tamamlanmadığından, $ el.scrollTop (eskival) değerini güvenilir bir şekilde ayarlayamadım. Bu çözümü benim için çalıştı buldum.

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

0
2018-02-20 17:29





Kaydırma konumunu, ofsetin üzerine, sayfanın / öğenin altına da taşıyabilirsiniz.

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

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

//set scroll position
$(window).scrollTop($(document).height() - ScrollFromBottom);

0
2017-09-13 18:49