Вопрос

Я делаю это на PHP, но это логическая проблема, поэтому я постараюсь написать это как можно более обобщенно.

Для начала вот как работает этот скрипт разбиения на страницы:

<Ол>
  • для ( рисует первые три страницы ссылки )
  • if ( нарисуйте многоточие (...), если есть страницы между страницами # 1 и # 3 )
  • for ( рисует текущую страницу и две страницы на каждой стороне ссылки )
  • if ( нарисуйте elipsis (...), если между страницами # 3 и # 5 есть страницы )
  • для ( создать последние три страницы ссылок )
  • Проблема в том, что при небольшом количестве страниц (я заметил это, когда число страниц было равно 10), должен быть многоточие, но ни одна не прорисована.

    На код:

    $page_count = 10; //in actual code this is set properly
    $current_page = 1; //in actual code this is set properly
    
    for ($i = 1;$i <= 3;$i++)
    {
        if ($page_count >= $i)
            echo $i;
    }
    
    if ($page_count > 3 && $current_page >= 7)
        echo "...";
    
    for ($i = $current_page - 2;$i <= current_page + 2;$i++)
    {
        if ($i > 3 && $i < $page_count - 2)
            echo $i;
    }
    
    if ($page_count > 13 && $current_page < $page_count - 5)
        echo "...";
    
    for ($i = $page_count - 2;$i <= $page_count;$i++)
    {
        if ($page_count > 3)
            echo $i;
    }
    

    Так что я считаю, что лучшей идеей было бы изменить один из двух многоточий, если в предложения включается случай, подобный этому, однако я пытался и озадачен.

    Также обратите внимание, что я сжал этот код для удобства чтения, поэтому не давайте советов, подобных " циклы for неэффективны, поскольку они будут пересчитывать current_page - 2 для каждой итерации " потому что я знаю :)

    <Ч>

    Для тех, кто хочет увидеть подробности о том, как работает эта логика, вот пример выходных данных (измененных) с итерациями $ page_count и $ current_page. http://rafb.net/p/TNa56h71.html

    Это было полезно?

    Решение

    <?php
    
    /**
     * windowsize must be odd
     *
     * @param int $totalItems 
     * @param int $currentPage 
     * @param int $windowSize 
     * @param int $anchorSize 
     * @param int $itemsPerPage 
     * @return void
     */
    function paginate($totalItems, $currentPage=1, $windowSize=3, $anchorSize=3, $itemsPerPage=10) {
        $halfWindowSize = ($windowSize-1)/2;
    
        $totalPages = ceil($totalItems / $itemsPerPage);
        $elipsesCount = 0;
        for ($page = 1; $page <= $totalPages; $page++) {
            // do we display a link for this page or not?
            if ( $page <= $anchorSize ||  
                $page > $totalPages - $anchorSize ||
                ($page >= $currentPage - $halfWindowSize &&
                $page <= $currentPage + $halfWindowSize) ||
                ($page == $anchorSize + 1 &&
                 $page == $currentPage - $halfWindowSize - 1) ||
                ($page == $totalPages - $anchorSize &&  
                 $page == $currentPage + $halfWindowSize + 1 ))
            {
                $elipsesCount = 0;
                if ($page == $currentPage)
                    echo ">$page< ";
                else
                    echo "[$page] ";
            // if not, have we already shown the elipses?
            } elseif ($elipsesCount == 0) {
                echo "... ";
                $elipsesCount+=1; // make sure we only show it once
            }
        }
        echo "\n";
    }
    
    //
    // Examples and output
    //
    
    paginate(1000, 1, 3, 3);
    // >1< [2] [3] ... [98] [99] [100] 
    
    paginate(1000, 7, 3, 3);
    // [1] [2] [3] ... [6] >7< [8] ... [98] [99] [100] 
    
    paginate(1000, 4, 3, 3);
    // [1] [2] [3] >4< [5] ... [98] [99] [100] 
    
    paginate(1000, 32, 3, 3);
    // [1] [2] [3] ... [31] >32< [33] ... [98] [99] [100] 
    
    paginate(1000, 42, 7, 2);
    // [1] [2] ... [39] [40] [41] >42< [43] [44] [45] ... [99] [100] 
    

    Другие советы

    Возможно, это слишком сложное решение, но оно работает.

    Я использовал здесь массив вместо простой печати, что позволяет мне " делать поверх " логика

    Часть проблемы возникает, когда «слева и справа от страницы» бывает совпадать с левым и правым плечами.

    function cdotinator ( $current_page, $page_count ) 
    {
      $stepsize = 3; 
      $elipse = '...';
      # Simple Case. 
      if ( $page_count <= 2 * $stepsize )
      {
        $out = range( 1, $page_count );
        $out[$current_page - 1 ] = '*' . $current_page . '*';
        return $out;
      }
      #Complex Case
      # 1) Create All Pages
      $out = range( 1, $page_count ); 
      # 2 ) Replace "middle" pages with "." placeholder elements 
      for( $i = $stepsize+1 ; $i <= ( $page_count - $stepsize ) ; $i ++ )
      {
        $out[ $i - 1 ] = '.' ; 
      }
      # 3.1 ) Insert the pages around the current page 
      for( $i =  max(1,( $current_page - floor($stepsize / 2) )) ;
           $i <= min( $page_count,( $current_page + floor( $stepsize/2))); 
           $i ++ )
      {
        $out[ $i - 1] = $i;
      }
      # 3.2 Bold Current Item
      $out[ $current_page - 1 ] = '*' . $current_page . '*' ; 
    
      # 4 ) Grep out repeated '.' sequences and replace them with elipses 
      $out2 = array(); 
      foreach( $out as $i => $v )
      {
        #  end, current  == peek() 
        end($out2);
        if( current($out2) == $elipse and $v == '.' )
        {
            continue;
        }
        if( $v == '.' )
        {
          $out2[] = $elipse; 
          continue;
        }
        $out2[]= $v;
      }
    
      return $out2;
    
    }
    

    Вывод можно посмотреть здесь: http://dpaste.com/92648/

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top