Reputation: 3986
I am using infinity scroll in my project. First it will fetch few records from MySQL database and show on page. Once page scroll down it make ajax query to server and load more data.
Is it possible to fetch all data at once from mysql database in json format and then perform load more on client side. So, basically I want no ajax request to database.
Here is the code which is working fine if I make ajax request on page scroll.
flag = true;
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()){
first = $('#first').val();
limit = $('#limit').val();
no_data = true;
if(flag && no_data){
flag = false;
$('#loader').show();
$.ajax({
url : 'ajax_html.php',
method: 'post',
data: {
start : first,
limit : limit
},
success: function( data ) {
flag = true;
$('#loader').hide();
if(data !=''){
first = parseInt($('#first').val());
limit = parseInt($('#limit').val());
$('#first').val( first+limit );
$('#timeline-conatiner').append( '<li class="year">'+year+'</li>');
$('#timeline-conatiner').append( data );
year--;
}else{
alert('No more data to show');
no_data = false;
}
},
error: function( data ){
flag = true;
$('#loader').hide();
no_data = false;
alert('Something went wrong, Please contact admin');
}
});
}
}
});
Upvotes: 0
Views: 1886
Reputation: 1758
If all data has been retrieved and added to DOM, then following script may be helpful. First add hidden
class to extra elements. Run this script after DOM is created.
$(".elements").each(function(index, el) { // `elements` is the common class for all elements on which this functionality is to be done
if (index >= maxLimitToShow) { // maxLimitToShow - number of elements to show in the beginning
$(el).addClass("hidden"); // for extra elements
}
});
Add css for class hidden
.hidden {
display: none;
}
And check when scroll has reached the bottom of page to show more items.
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) { // checks if scroll reached at bottom
var elements = $(".elements.hidden"); // fetch all hidden elements
elements.each(function (index, el) {
if (index < singleRowLimit) { // singleRowLimit - number of elements to show in one scroll
$(el).removeClass('hidden');
}
});
}
});
EDIT - without using CSS - hide/show
If all data has been retrieved and added to DOM, then following script may be helpful. First add hidden
class to extra elements. Run this script after DOM is created.
$(".elements").each(function(index, el) { // `elements` is the common class for all elements on which this functionality is to be done
if (index >= maxLimitToShow) { // maxLimitToShow - number of elements to show in the beginning
$(el).addClass("hidden").hide(); // for extra elements
}
});
And check when scroll has reached the bottom of page to show more items.
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) { // checks if scroll reached at bottom
var elements = $(".elements.hidden"); // fetch all hidden elements
elements.each(function (index, el) {
if (index < singleRowLimit) { // singleRowLimit - number of elements to show in one scroll
$(el).removeClass('hidden').show();
}
});
}
});
Upvotes: 1
Reputation: 41
I would say you don't need infinity scroller (or whatever) at all to do what u want... but since u have it all nicely working and I suspect u might decide u want that 'lazy load' type functionality back at some point u could do the lazy thing...
Simply try playing around with the first and limit param values in your example...
Say... first = 0 and limit = some really big number...
I think u can set some values and force a single ajax call on page load very easily.
Upvotes: 1
Reputation: 21661
This is untested and just an example of the method, Sorry I don't have time for a full example but this should give you the idea.
//data cache
var cache = ['one','two', 'three' .....];
//current location in cache
var current = 0;
//ajax request object
var request;
if($(window).scrollTop() + $(window).height() == $(document).height()){
var cache_total = cache.length;
//add next item to page & increase the current pointer
$('#timeline-conatiner').append( cache[current] );
++current;
if( current - cache.length < 50 ){
//if we only have 50 items not shown in cache pull next results with ajax and add to cache
if( !request ){
//also youll want to keep track if you have a pending request that hasn't returned yet, to prevent race conditions.
request = $.ajax( .... ).success( function( data ){
$.extend( cache, data ); //or push each if you like
}).always( function(){
request = false; //should be false on finish but just because.
});
} //end if request
//make sure to properly offset the data using the total in the cache to prevent pulling duplicates. eg SELECT ... LIMIT {cache.length}, 50
} // end if cached
} //end scroll
See the issue with what you have above is the user needs to wait for the ajax call to finish, which essentially turns it into a synchronous request ( like reloading the page ). You want to keep it asynchronous as ajax is intended to be. So instead of displaying the results of the ajax, you buffer them and keep some data you are not showing. Then on scroll show some buffered data and after that fill the cache back up.
Obviously this makes it much more complex to code, but the advantage is you don't need to pull a massive amount of data at one time and the user wont get the delay from halting on the ajax request. You'll have to balance the time the request takes with the amount of data in the cache so you always have some data in there. This depends on how much space data
takes to render and how long the ajax query takes.
Upvotes: 1