如何使用分页实现同位素

Posted

技术标签:

【中文标题】如何使用分页实现同位素【英文标题】:How to implement Isotope with Pagination 【发布时间】:2016-04-24 08:28:56 【问题描述】:

我正在尝试在我的 WordPress 网站上实现同位素分页(这对大多数人来说显然是个问题)。如果我能弄清楚一些事情,我想出了一个可行的方案。

在我的页面上,我有这部分同位素脚本 -

$('.goforward').click(function(event) 
    var href = $(this).attr('href');
    $('.isotope').empty();
    $('.isotope').load(href +".html .isotope > *");
    $( 'div.box' ).addClass( 'isotope-item' );
    $container.append( $items ).isotope( 'insert', $items, true );
    event.preventDefault();
);

然后我正在使用我从here 修改的分页功能来拥有'goforward'类——

function isotope_pagination($pages = '', $range = 2)
  
     $showitems = ($range * 2)+1;  

     global $paged;
     if(empty($paged)) $paged = 1;

     if($pages == '')
     
         global $wp_query;
         $pages = $wp_query->max_num_pages;
         if(!$pages)
         
             $pages = 1;
         
        

     if(1 != $pages)
     
         echo "<div class='pagination'>";
         for ($i=1; $i <= $pages; $i++)
         
             if (1 != $pages &&( !($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems ))
             
                 echo ($paged == $i)? "<a href='".get_pagenum_link($i)."' class='inactive goforward'>".$i."</a>":"<a href='".get_pagenum_link($i)."' class='inactive goforward' >".$i."</a>";
             
         
         echo "</div>\n";
     

第一个问题 - 我遇到了过滤/排序问题。它可以很好地过滤第一页,但不会排序。在第二页或加载的任何其他页面上,在该页面上重新开始时,它不会追加/插入甚至过滤/排序。相反,当尝试这样做时,它给了我这个错误--

Uncaught TypeError: Cannot read property '[object Array]' of undefined

第二个问题 - 加载页面片段时,存在延迟,并且当前页面在下一个页面片段加载到位之前仍然可见。

我知道很多人在同位素和分页方面存在问题,通常,即使同位素作者不推荐,最终还是使用无限滚动。

所以我的理论是通过 load() 加载内容并进行某种回调以仅显示过滤后的项目。

关于如何实现这一点的任何想法?

我的整个同位素脚本 ---

$(function () 
    var selectChoice, updatePageState, updateFiltersFromObject,
    $container = $('.isotope');
    $items = $('.item');  

    ////////////////////////////////////////////////////////////////////////////////////
    /// 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;
    pgCount++;

    $('.goback').click(function() 
        $('.isotope').empty();
        $('.isotope').load("/page/<?php echo --$paged;?>/?<?php echo $_SERVER["QUERY_STRING"]; ?>.html .isotope > *");
        $container.append( $items ).isotope( 'insert', $items, true );
        $( 'div.box' ).addClass( 'isotope-item' );
   );

   $('.goforward').click(function(event) 
       var href = $(this).attr('href');
       $('.isotope').empty();
       $('.isotope').load(href +".html .isotope > *");
       $( 'div.box' ).addClass( 'isotope-item' );
       $container.append( $items ).isotope( 'insert', $items, true );
       event.preventDefault();
   );
);
        //////////////////////////////////////////////////////
        // 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);
      ); 
);

【问题讨论】:

错误Uncaught TypeError: Cannot read property '[object Array]' of undefined在哪一行生成? @mani jquery.isotope.min.js:13 Uncaught TypeError: Cannot read property '[object Array]' of undefined 您确定复制/粘贴了整个脚本吗?因为看起来您的最后两个块(从初始化计数器开始......)超出了 jQuery 就绪 IIFE 的范围。如果是这种情况,$container 将不会被定义,可能就是 TypeError。 我认为你在这一行有错误:$('.isotope').load(href +".html .isotope > *");那应该是: $('.isotope').load(href +" .html .isotope > *"); (在 +" 和 .html 之间缺少一个空格字符)。这个空格是必要的,以使 jquery 了解您正在使用仅获取传入页面的一部分的特殊语法......这可能意味着整个返回的页面将被添加到 .isotope 元素中,这可能会导致所有其他功能无法正常工作,因为在页面层次结构中的预期位置找不到元素。 另外,另一个问题:您只在启动调用中定义 $items 变量值:这意味着该变量将包含在启动时页面中的项目,而不是现在在页面:如果容器包含 A、B、C,这意味着在页面初始化时您将 $items 分配给 A、B、C。然后调用 .load,容器内容现在是 D、E、F,但 $items 仍然包含 A、B、C!因此,您必须添加 $items = $('.item');就在 container.append(... 之前,否则这是行不通的:如果你不这样做,你总是会调用 A、B、C 上的同位素,而这正是正在发生的事情! 【参考方案1】:

懒加载器效果很好,我自己试过 检查代码笔

你也可以试试:

var $container = $('#container').isotope(
    itemSelector: itemSelector,
    masonry: 
        columnWidth: itemSelector,
        isFitWidth: true
    
);

【讨论】:

【参考方案2】:

您是否检查过以下链接:

https://codepen.io/Igorxp5/pen/ojJLQE

它有一个同位素分页的工作示例。

请查看 JS 部分中的以下代码块:

var $container = $('#container').isotope(
    itemSelector: itemSelector,
    masonry: 
        columnWidth: itemSelector,
        isFitWidth: true
    
);

【讨论】:

过滤器不是分页!【参考方案3】:

如果有用,请查看以下链接

https://mixitup.kunkalabs.com/extensions/pagination/

您也可以使用惰性加载器进行分页。

希望对你有帮助

【讨论】:

谢谢,但它警告使用超过 150 个项目。我需要能够过滤的内容远不止这些。 这是为 wordpress 编写的解决方案,但确实展示了实现分页的想法,希望对您有所帮助...tannermoushey.com/2012/12/isotope-paging【参考方案4】:

&lt;a href="http://codepen.io/Igorxp5/pen/ojJLQE"&gt;&lt;/a&gt;

我想这会对你有所帮助。

参考这个网址

【讨论】:

兄弟,您在发布 codepen/fiddle 时也需要提供一些随附的代码。尝试从那里复制一些代码,并以可以回答此问题的方式对其进行表述。 鼓励链接到外部资源,但请在链接周围添加上下文,以便您的其他用户了解它是什么以及为什么存在。始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线。

以上是关于如何使用分页实现同位素的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 UIScrollViewDelegate 方法重新实现 UIScrollView 分页

如何优雅地实现分页查询

如何使用 pjax 实现 Codeigniter 默认分页

如何使用 mybatis 实现分页

SwiftUI:如何在用户滑动时实现分页? (之前使用的 UICollectionView -> 启用分页)

如何使用 kotlin 实现分页