2012-03-23 18 views
22

मेरे पास एक ऐसा पृष्ठ है जो संदेश प्रदर्शित करता है और मैं इसे फेसबुक की तरह काम करना चाहता हूं, लेकिन आलसी लोडर के बिना। संदेश कालक्रम क्रम में प्रदर्शित होते हैं, हाल ही में अंतिम।jquery - सूची में आइटम को प्रीपेड करते समय विंडो को स्क्रॉल स्थिति बदलने से रोकें?

मेरी संदेश सूची प्रारंभ में हाल ही के संदेशों की एक्स संख्या पॉप्युलेट की गई है, और विंडो नीचे स्क्रॉल की गई है। जब उपयोगकर्ता धागे को पढ़ना शुरू करता है, तो वे नीचे से ऊपर तक पढ़ते हैं। यदि वे शीर्ष पर पहुंचते हैं, तो वे अधिक संदेश लोड कर सकते हैं ... मैं उन्हें एक बटन पर क्लिक करता हूं ... फेसबुक में आलसी लोडर है। सूची में नए संदेश प्रीपेड किए गए हैं।

समस्या: जैसा कि नए संदेश प्रीपेड किए गए हैं, मौजूदा संदेशों को धक्का दिया जाता है, जिससे उपयोगकर्ता अपनी "देखने" जगह खो देता है। जब मैं नए संदेश जोड़ता हूं तो मैं उपयोगकर्ता की वर्तमान दृश्य स्थिति कैसे रख सकता हूं? उदाहरण के लिए, फेसबुक में एक लंबा संदेश धागा खोलें, नए संदेशों को जोड़ने के लिए शीर्ष पर स्क्रॉल करें ... स्क्रॉल स्थिति होने के बावजूद आपका दृश्य स्थान परिवर्तित नहीं होता है।

उत्तर

41

स्टोर पहला संदेश इससे पहले कि आप नए संदेशों पहले जोड़ें, और आप पहले जोड़ें के बाद, के लिए कि संदेश की भरपाई स्क्रॉल स्थापित करने के लिए एक संदर्भ:

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

डेमो: http://jsfiddle.net/GRnQY/

संपादित: मैंने देखा कि आप इसे एक बटन के साथ चाहते थे। आप एक छोटे से अधिक गणित करना पड़ सकता है:

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

डेमो: http://jsfiddle.net/GRnQY/5/

+6

दूसरा समाधान अद्भुत है - आपको बहुत धन्यवाद, यह एक "फेसबुक असीमित स्क्रॉल" को लागू करने के लिए बहुत उपयोगी था। –

+0

यदि आप AJAX का उपयोग कर रहे हैं, तो '$ (selector) .scrollTop (firstMsg.offset()। Top-curOffset) जोड़ें; 'ठीक से काम करने के लिए स्क्रॉल के लिए AJAX' सफलता 'विशेषता पर – user3284463

+0

बहुत बढ़िया! धन्यवाद जेफ! – Can

5

यहाँ jQuery के लिए कोई ज़रूरत नहीं, बस तत्वों scrollHeight में परिवर्तन के लिए जाँच करें और उसके अनुसार scrollTop समायोजित, अर्थात्:

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

डेमो

http://jsfiddle.net/fkqqv28e/

jQuery

एक jQuery संग्रह से देशी डोम नोड पहुंचने के लिए, सरणी पहुँच का उपयोग करें; यानी:

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

मैं बस इसके एक बदलाव में भाग गया। मैंने बड़ी संख्या में तत्वों को अलग किया, उन्हें संसाधित किया और फिर उन्हें फिर से जोड़ा। यह क्रोम में सिंक्रनाइज़ नहीं होता है इसलिए मैं $ el.scrollTop (पुराना) विश्वसनीय रूप से सेट नहीं कर सका। मैंने पाया कि यह समाधान मेरे लिए काम करता है।

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

यहां आने वाले कुछ लोग बस वर्तमान फोकस के बिना सामग्री जोड़ना चाहते हैं। ऊपर जेफ बी के डेमो संशोधित करना क्लिक करें घटना लक्ष्य का उपयोग करने के लिए इस मुहावरा अधिक पोर्टेबल बनाता है:

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

सी.एफ़ http://jsfiddle.net/bwz8uLvt/1/ (ऊपर जेफ बी के डेमो का संस्करण लेकिन पृष्ठ में एक मनमानी बिंदु पर [अधिक जोड़ें] बटन के साथ)।

0

आप पृष्ठ/तत्व के नीचे ऑफसेट पर आधारित स्क्रॉल स्थिति भी रख सकते हैं।

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

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

//set scroll position 
$(window).scrollTop($(document).height() - ScrollFromBottom); 
संबंधित मुद्दे