简体   繁体   English

加载内容时停止无限滚动从跳转到页面末尾

[英]Stop infinite scroll from jumping to end of page when loading content

I have implemented infinite scroll with isotope on my website and I am having a problem with loading posts. 我在网站上实现了同位素的无限滚动,并且在加载帖子时遇到问题。 The posts load fine, but lets say I scroll down to load more posts but I am still viewing the posts already there, infinite scroll jumps to the bottom of the page whenever new posts are loaded. 帖子加载正常,但可以说我向下滚动以加载更多帖子,但是我仍在查看那里的帖子,每当加载新帖子时,无限滚动就会跳到页面底部。 How can I stop this behavior and maintain the position on the page even when more posts are loaded? 即使加载了更多帖子,如何停止这种行为并保持页面上的位置?

My script -- 我的剧本-

$(function () {
        var selectChoice, updatePageState, updateFiltersFromObject,
            $container = $('.isotope');
        ////////////////////////////////////////////////////////////////////////////////////
        /// EVENT HANDLERS
        ////////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////
        // Mark filtering element as active/inactive and trigger filters update
        $('.js-filter').on( 'click', '[data-filter]', function (event) {
          event.preventDefault();
          selectChoice($(this), {click: true});
          $container.trigger('filter-update');
        });
        //////////////////////////////////////////////////////
        // Sort filtered (or not) elements
        $('.js-sort').on('click', '[data-sort]', function (event) {
          event.preventDefault();
          selectChoice($(this), {click: true});
          $container.trigger('filter-update');
        });
        //////////////////////////////////////////////////////
        // Listen to filters update event and update Isotope filters based on the marked elements
        $container.on('filter-update', function (event, opts) {
          var filters, sorting, push;
          opts = opts || {};
          filters = $('.js-filter li.active a:not([data-filter="all"])').map(function () {
            return $(this).data('filter');
          }).toArray();
          sorting = $('.js-sort li.active a').map(function () {
            return $(this).data('sort');
          }).toArray();
          if (typeof opts.pushState == 'undefined' || opts.pushState) {
            updatePageState(filters, sorting);
          }
          $container.isotope({
            filter: filters.join(''),
            sortBy: sorting
          });

        });
        //////////////////////////////////////////////////////
        // Set a handler for history state change
        History.Adapter.bind(window, 'statechange', function () {
          var state = History.getState();
          updateFiltersFromObject(state.data);
          $container.trigger('filter-update', {pushState: false});
        });
        ////////////////////////////////////////////////////////////////////////////////////
        /// HELPERS FUNCTIONS
        ////////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////
        // Build an URI to get the query string to update the page history state
        updatePageState = function (filters, sorting) {
          var uri = new URI('');
          $.each(filters, function (idx, filter) {
            var match = /^\.([^-]+)-(.*)$/.exec(filter);
            if (match && match.length == 3) {
              uri.addSearch(match[1], match[2]);
            }
          });
          $.each(sorting, function (idx, sort) {
            uri.addSearch('sort', sort);
          });
          History.pushState(uri.search(true), null, uri.search() || '?');
        };
        //////////////////////////////////////////////////////
        // Select the clicked (or from URL) choice in the dropdown menu
        selectChoice = function ($link, opts) {
          var $group = $link.closest('.btn-group'),
              $li = $link.closest('li'),
              mediumFilter = $group.length == 0;
          if (mediumFilter) {
            $group = $link.closest('.js-filter');
          }

          if (opts.click) {
            $li.toggleClass('active');
          } else {
            $li.addClass('active');
          }
          $group.find('.active').not($li).removeClass('active');
          if (!mediumFilter) {
            if ($group.find('li.active').length == 0) {
              $group.find('li:first-child').addClass('active');
            }
            $group.find('.selection').html($group.find('li.active a').first().html());
          }
        };
        //////////////////////////////////////////////////////
        // Update filters by the values in the current URL
        updateFiltersFromObject = function (values) {
          if ($.isEmptyObject(values)) {
            $('.js-filter').each(function () {
                selectChoice($(this).find('li').first(), {click: false});
            });
            selectChoice($('.js-sort').find('li').first(), {click: false});
          } else {
            $.each(values, function (key, val) {
              val = typeof val == 'string' ? [val] : val;
              $.each(val, function (idx, v) {
                var $filter = $('[data-filter=".' + key + '-' + v + '"]'),
                    $sort = $('[data-sort="' + v + '"]');
                if ($filter.length > 0) {
                  selectChoice($filter, {click: false});
                } else if ($sort.length > 0) {
                  selectChoice($sort, {click: false});
                }
              });
            });
          }
        };
        ////////////////////////////////////////////////////////////////////////////////////
        /// Initialization
        ////////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////
        // Initialize Isotope
$container.imagesLoaded( function(){
        $container.isotope({
  masonry: { resizesContainer: true },
          itemSelector: '.item',
          getSortData: {
 date: function ( itemElem ) {
      var date = $( itemElem ).find('.thedate').text();
      return parseInt( date.replace( /[\(\)]/g, '') );
    },
area: function( itemElem ) { // function
      var area = $( itemElem ).find('.thearea').text();
      return parseInt( area.replace( /[\(\)]/g, '') );
    },
price: function( itemElem ) { // function
      var price = $( itemElem ).find('.theprice').text();
      return parseInt( price.replace( /[\(\)]/g, '') );
    }
          }
        });

var total = $(".next a:last").html();
var pgCount = 1;
var numPg = total;

    // jQuery InfiniteScroll Plugin.
    $container.infinitescroll({
 contentSelector  : '.isotope',
 speed : 'fast',
behavior: 'simplyrecipes',
         navSelector  : '#pagi',    // selector for the paged navigation 
        nextSelector : '#pagi a.next',  // selector for the NEXT link (to page 2)
        itemSelector : '.item',     // selector for all items you'll retrieve
        animate: true,
debug: true,
        loading: {
selector: '#infscr-loading',
            finishedMsg: 'No more content to load.'
        }
    },
    // Trigger Masonry as a callback.
    function( newElements ) {
        pgCount++;

        if(pgCount == numPg) {
            $(window).unbind('.infscr');
            $container.isotope('reload');
            $container.append( newElements ).isotope( 'appended', newElements, true );
            $('#infscr-loading').find('em').text('No more content to load.');
            $('#infscr-loading').animate({
                opacity: 1
            }, 200);
            setTimeout(function() {
                $('#infscr-loading').animate({
                    opacity: 0
                }, 300);
            });
        } else {
            loadPosts(newElements);
        }
    }); 
});

function loadPosts(newElements) {
    // Hide new posts while they are still loading.
    var newElems = $( newElements ).css({ opacity: 0 });
    // Ensure that images load before adding to masonry layout.
    newElems.imagesLoaded(function() {
        // Show new elements now that they're loaded.
        newElems.animate({ opacity: 1 });
        $container.isotope( 'appended', newElems, true );      
    });
}
        //////////////////////////////////////////////////////
        // Initialize counters
        $('.stat-count').each(function () {
          var $count = $(this),
              filter = $count.closest('[data-filter]').data('filter');
          $count.html($(filter).length);
        });
        //////////////////////////////////////////////////////
        // Set initial filters from URL
        updateFiltersFromObject(new URI().search(true));
        $container.trigger('filter-update', {pushState: false});
      }); 
});

You can start by overriding the default animate property of infinite-scroll 您可以从覆盖无限滚动的默认动画属性开始

$container.infinitescroll({
    animate:false, //this does just that
});

And about your dublicate entry for every request (or perhaps some requests ), It has something to do with your backend ie the way you are offseting the data 关于每个请求(或某些请求)的重复条目 ,这与后端有关,即偏移数据的方式

Infinite Scroll works great with page numbers ie it Sends 2,3,4,5,6 ... So For every request its sends that request. Infinite Scroll可以很好地处理页码,即它发送2,3,4,5,6 ...因此,对于每个请求,它都会发送该请求。

I think you are using page offset instead , and you will probably end up with duplicate entries . 我认为您使用的是页面偏移量 ,并且最终可能会有重复的条目。

If you are using php as your receiving end ... this might help 如果您使用php作为接收端...这可能会有所帮助

//In your Controller
$temp = ( $page_offset * $per_page );
$offset = $temp - $per_page ;

//In your model
$this->db->query("SELECT * FROM GALLERY OFFSET $offset limit 10");

This is just a rough idea , I hope it helps. 这只是一个粗略的主意,希望对您有所帮助。

If it does , Care to Check out Sticky Bubble ? 如果是这样,是否要检查粘性气泡 - A game available for free on Google Play . -Google Play提供免费游戏

Cheers :) 干杯:)

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

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