简体   繁体   English

无限滚动:从数据库加载所有数据并滚动以显示更多

[英]infinity scroll: Load all data from database and scroll to show more

I am using infinity scroll in my project. 我在项目中使用无限滚动。 First it will fetch few records from MySQL database and show on page. 首先,它将从MySQL数据库中获取一些记录并显示在页面上。 Once page scroll down it make ajax query to server and load more data. 页面向下滚动后,它将向服务器进行ajax查询并加载更多数据。

Is it possible to fetch all data at once from mysql database in json format and then perform load more on client side. 是否可以一次从json格式的mysql数据库中获取所有数据,然后在客户端执行更多加载。 So, basically I want no ajax request to database. 因此,基本上我不需要数据库的ajax请求。

Here is the code which is working fine if I make ajax request on page scroll. 如果我在页面滚动上发出ajax请求,则以下代码可以正常工作。

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


    }
}); 

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 ). 看到上面的问题是用户需要等待ajax调用完成,这实际上将其转换为同步请求(如重新加载页面)。 You want to keep it asynchronous as ajax is intended to be. 您想要像ajax一样保持异步。 So instead of displaying the results of the ajax, you buffer them and keep some data you are not showing. 因此,您不必缓冲ajax的结果,而是缓冲它们并保留一些未显示的数据。 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. 显然,这使编写代码变得更加复杂,但是优点是您不需要一次提取大量数据,并且用户不会因暂停ajax请求而延迟。 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. 这取决于呈现data需要多少空间以及ajax查询要花费多长时间。

If all data has been retrieved and added to DOM, then following script may be helpful. 如果已检索所有数据并将其添加到DOM,则以下脚本可能会有所帮助。 First add hidden class to extra elements. 首先将hidden类添加到其他元素。 Run this script after DOM is created. 创建DOM后运行此脚本。

$(".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的类添加CSS

.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 编辑 -不使用CSS-隐藏/显示

If all data has been retrieved and added to DOM, then following script may be helpful. 如果已检索所有数据并将其添加到DOM,则以下脚本可能会有所帮助。 First add hidden class to extra elements. 首先将hidden类添加到其他元素。 Run this script after DOM is created. 创建DOM后运行此脚本。

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

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... 说...首先= 0且限制=一些非常大的数字...

I think u can set some values and force a single ajax call on page load very easily. 我认为您可以设置一些值,并非常容易地在页面加载上强制单个ajax调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM