How to do page navigation for many, many pages? Logarithmic page navigation

后端 未结 4 1123
闹比i
闹比i 2020-11-28 05:49

What\'s the best way of displaying page navigation for many, many pages?

(Initially this was posted as a how-to tip with my answer included in the question. I\'ve

4条回答
  •  一生所求
    2020-11-28 06:16

    Here's my solution - use "Logarithmic Page Navigation":

    This can be achieved by having page numbers distributed logarithmically, according to distance from either the endpoints or the current page. Here's an example of what I mean:

    1 2 3 4 5 6 . 10 . 20 . 30 . 40 . 50 .. 100 .. 200 . 210 . 220 . 230 . 240 . 250 . 252 253 254 255 256 257 258 259 260 261 262 . 270 . 280 . 290 . 300 . 310 .. 400 .. 500 .. 600 .. 700 .. 800 .. 900 .. 950 . 960 . 970 . 980 . 990 . 995 996 997 998 999 1000

    Notice how in the gaps, numbering goes from 1s, to 10s, to 100s (etc.). (I use powers of 10, but in principle you could use a different scheme - powers of 2, say).

    I wrote some code that does this back in 2004, and thought I'd share it here. There are PHP and ASP versions, but the logic ought to be simple to translate into any language. Note that the bit at the bottom (in both cases) just displays some examples. Obviously the formatting will need customization to match your webpage (or application), so it's pretty basic here. Alter LINKS_PER_STEP in paginationHTML to determine how many numbers get displayed before the step size increases, as you move away from the endpoints or current page.

    For a more compact output you could also consider altering the code so that the numbering is not "dense" around the endpoints (i.e. dense only around the current page).

    Here's the code:

    PHP version:

    ' . $p . '';
      return '' . $p . '';
    }
    
    
    // Used by paginationHTML below...
    function paginationGap($p1, $p2)
    {
      $x = $p2-$p1;
      if ($x==0) return '';
      if ($x==1) return ' ';
      if ($x<=10) return ' . ';
      if ($x<=100) return ' .. ';
      return ' ... ';
    }
    
    
    // URL requires the $page number be appended to it.
    // e.g. it should end in '&page=' or something similar.
    function paginationHTML($page, $lastPage, $URL)
    {
      $LINKS_PER_STEP = 5;
    
      // Nav buttons
    
      if ($page>1)
        $result = '
     ' . '
    '; else $result = ' '; $result .= '  ' . $page . '  '; if ($page<$lastPage) $result .= '
     ' . '
    '; else $result .= ' '; $result .= "
    "; // Now calculate page links... $lastp1 = 1; $lastp2 = $page; $p1 = 1; $p2 = $page; $c1 = $LINKS_PER_STEP+1; $c2 = $LINKS_PER_STEP+1; $s1 = ''; $s2 = ''; $step = 1; while (true) { if ($c1>=$c2) { $s1 .= paginationGap($lastp1,$p1) . paginationLink($p1,$page,$URL); $lastp1 = $p1; $p1 += $step; $c1--; } else { $s2 = paginationLink($p2,$page,$URL) . paginationGap($p2,$lastp2) . $s2; $lastp2 = $p2; $p2 -= $step; $c2--; } if ($c2==0) { $step *= 10; $p1 += $step-1; // Round UP to nearest multiple of $step $p1 -= ($p1 % $step); $p2 -= ($p2 % $step); // Round DOWN to nearest multiple of $step $c1 = $LINKS_PER_STEP; $c2 = $LINKS_PER_STEP; } if ($p1>$p2) { $result .= $s1 . paginationGap($lastp1,$lastp2) . $s2; if (($lastp2>$page)||($page>=$lastPage)) return $result; $lastp1 = $page; $lastp2 = $lastPage; $p1 = $page+1; $p2 = $lastPage; $c1 = $LINKS_PER_STEP; $c2 = $LINKS_PER_STEP+1; $s1 = ''; $s2 = ''; $step = 1; } } } ?>























    ASP version:

    <%
    
    ' Used by paginationHTML below...
    Function paginationLink(p, page, URL)
      if p=page then
        paginationLink = "" & p & ""
      else
        paginationLink = "" & p & ""
      end if
    End Function
    
    
    ' Used by paginationHTML below...
    Function paginationGap(p1, p2)
      Dim x
      x = p2-p1
      if x=0 then
        paginationGap = ""
      elseif x=1 then
        paginationGap = " "
      elseif x<=10 then
        paginationGap = " . "
      elseif x<=100 then
        paginationGap = " .. "
      else
        paginationGap = " ... "
      end if
    End Function
    
    
    ' URL requires the page number be appended to it.
    ' e.g. it should end in "&page=" or something similar.
    Function paginationHTML(page, lastPage, URL)
      const LINKS_PER_STEP = 5
      Dim p1, p2, c1, c2, s1, s2, lastp1, lastp2, step
    
      ' Nav buttons
      if page>1 then
        paginationHTML = "
     " & _ "
    " else paginationHTML = " " end if paginationHTML = paginationHTML & "  " & page & "  " if page " & _ "
    " else paginationHTML = paginationHTML & " " end if paginationHTML = paginationHTML & "
    " ' Now calculate page links... lastp1 = 1 lastp2 = page p1 = 1 p2 = page c1 = LINKS_PER_STEP+1 c2 = LINKS_PER_STEP+1 s1 = "" s2 = "" step = 1 do if c1>=c2 then s1 = s1 & paginationGap(lastp1, p1) & paginationLink(p1, page, URL) lastp1 = p1 p1 = p1+step c1 = c1-1 else s2 = paginationLink(p2, page, URL) & paginationGap(p2, lastp2) & s2 lastp2 = p2 p2 = p2-step c2 = c2-1 end if if c2=0 then step = step*10 p1 = p1+step-1 ' Round UP to nearest multiple of step p1 = p1-(p1 mod step) p2 = p2-(p2 mod step) ' Round DOWN to nearest multiple of step c1 = LINKS_PER_STEP c2 = LINKS_PER_STEP end if if p1>p2 then paginationHTML = paginationHTML & s1 & paginationGap(lastp1, lastp2) & s2 if (lastp2>page) or (page>=lastPage) then exit do lastp1 = page lastp2 = lastPage p1 = page+1 p2 = lastPage c1 = LINKS_PER_STEP c2 = LINKS_PER_STEP+1 s1 = "" s2 = "" step = 1 end if loop End Function %>


    <%=paginationHTML(1,1,"?page=")%>


    <%=paginationHTML(2,3,"?page=")%>


    <%=paginationHTML(3,3,"?page=")%>


    <%=paginationHTML(73,100,"?page=")%>


    <%=paginationHTML(4,100,"?page=")%>


    <%=paginationHTML(257,1000,"?page=")%>


    <%=paginationHTML(7062,10555,"?page=")%>


    <%=paginationHTML(22080,503456,"?page=")%>

    Javascript version (within complete test page):

    
    
    
      Logarithmic Pagination Demo
      
      
    
    
      
    Select number of pages:     and records per page:    

    Go to page:
    Column Heading...
    Go to page:

提交回复
热议问题