- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
(最初这是作为操作提示发布的,我的答案包含在问题中。我现在将我的答案分成下面的“答案”部分)。
<小时/>更具体地说:
假设您要向用户显示一组记录,这些记录分为固定大小的页面(例如 Google 搜索的结果)。如果只有几个页面,您可以在结果末尾显示一个页面导航区域,如下所示:
[ << ] [<] 1 2 3 4 5 6 7 8 9 10 11 12 13 [ > ] [ >> ]
但是,如果结果超过 20 或 30 页,这很快就会变得不方便。
有时你会看到这样的东西:
[ << ] [<] ... 665 666 667 668 669 670 671 672 673 ... [ > ] [ >> ]
或者这个:
[ << ] [<] 1 2 3 ... 667 668 669 670 671 ... 845 846 847 [ > ] [ >> ]
但在这两种情况下,导航到“...”部分中间的任何位置都需要多次单击鼠标。有时会提供直接输入页码的输入框;否则(假设我们在这里讨论的是网页)精明的用户可能会查看 URL 以查看是否可以直接编辑它。
如果有一个分页显示,让用户只需点击几下鼠标就可以到达任何页面,而不需要有太多的链接,那就太好了。
如何最好地实现这一目标?
最佳答案
这可以通过根据距端点或当前页面的距离以对数方式分布页码来实现。这是我的意思的一个例子:
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
请注意间隙中编号如何从 1 变为 10、100(等等)。 (我使用 10 的幂,但原则上您可以使用不同的方案 - 比如说 2 的幂)。
我在 2004 年编写了一些执行此操作的代码,并想在这里分享它。有 PHP 和 ASP 版本,但逻辑应该很简单,可以翻译成任何语言。请注意,底部的位(在这两种情况下)仅显示一些示例。显然,格式需要自定义才能匹配您的网页(或应用程序),因此这里的格式非常基本。更改 paginationHTML
中的 LINKS_PER_STEP
以确定当您离开端点或当前页面时步长增加之前显示的数字数量。
为了获得更紧凑的输出,您还可以考虑更改代码,以使端点周围的编号不会“密集”(即仅在当前页面周围密集)。
代码如下:
<?
// Used by paginationHTML below...
function paginationLink($p, $page, $URL)
{
if ($p==$page) return '<b style="color:#C0C0C0">' . $p . '</b>';
return '<a href="' . $URL . $p . '">' . $p . '</a>';
}
// 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 = '<form action="' . $URL . '1" method="POST" style="display:inline"><input type="submit" value=" |< "></form> ' .
'<form action="' . $URL . ($page-1) . '" method="POST" style="display:inline"><input type="submit" value=" < "></form>';
else $result = '<input type="button" value=" |< " disabled> <input type="button" value=" < " disabled>';
$result .= ' ' . $page . ' ';
if ($page<$lastPage)
$result .= '<form action="' . $URL . ($page+1) . '" method="POST" style="display:inline"><input type="submit" value=" > "></form> ' .
'<form action="' . $URL . $lastPage . '" method="POST" style="display:inline"><input type="submit" value=" >| "></form>';
else $result .= '<input type="button" value=" > " disabled> <input type="button" value=" >| " disabled>';
$result .= "<br>";
// 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;
}
}
}
?>
<br><br><br>
<?=paginationHTML(1,1,'?page=')?>
<br><br><br>
<?=paginationHTML(2,3,'?page=')?>
<br><br><br>
<?=paginationHTML(3,3,'?page=')?>
<br><br><br>
<?=paginationHTML(73,100,'?page=')?>
<br><br><br>
<?=paginationHTML(4,100,'?page=')?>
<br><br><br>
<?=paginationHTML(257,1000,'?page=')?>
<br><br><br>
<?=paginationHTML(7062,10555,'?page=')?>
<br><br><br>
<?=paginationHTML(22080,503456,'?page=')?>
<%
' Used by paginationHTML below...
Function paginationLink(p, page, URL)
if p=page then
paginationLink = "<b style=""color:#C0C0C0"">" & p & "</b>"
else
paginationLink = "<a href=""" & URL & p & """>" & p & "</a>"
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 = "<form action=""" & URL & "1"" method=""POST"" style=""display:inline""><input type=""submit"" value="" |< ""></form> " & _
"<form action=""" & URL & (page-1) & """ method=""POST"" style=""display:inline""><input type=""submit"" value="" < ""></form>"
else
paginationHTML = "<input type=""button"" value="" |< "" disabled> <input type=""button"" value="" < "" disabled>"
end if
paginationHTML = paginationHTML & " " & page & " "
if page<lastPage then
paginationHTML = paginationHTML & "<form action=""" & URL & (page+1) & """ method=""POST"" style=""display:inline""><input type=""submit"" value="" > ""></form> " & _
"<form action=""" & URL & lastPage & """ method=""POST"" style=""display:inline""><input type=""submit"" value="" >| ""></form>"
else
paginationHTML = paginationHTML & "<input type=""button"" value="" > "" disabled> <input type=""button"" value="" >| "" disabled>"
end if
paginationHTML = paginationHTML & "<br>"
' 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
%>
<br><br><br>
<%=paginationHTML(1,1,"?page=")%>
<br><br><br>
<%=paginationHTML(2,3,"?page=")%>
<br><br><br>
<%=paginationHTML(3,3,"?page=")%>
<br><br><br>
<%=paginationHTML(73,100,"?page=")%>
<br><br><br>
<%=paginationHTML(4,100,"?page=")%>
<br><br><br>
<%=paginationHTML(257,1000,"?page=")%>
<br><br><br>
<%=paginationHTML(7062,10555,"?page=")%>
<br><br><br>
<%=paginationHTML(22080,503456,"?page=")%>
<!doctype html>
<html>
<head>
<title>Logarithmic Pagination Demo</title>
<style>
body {background:#C0C0C0;font-family:Arial,Helvetica,sans-serif;font-size:16px;text-align:left}
div {margin:0;padding:0}
div#setupDiv {margin:40px;text-align:center}
table#datarows {border-collapse:collapse;margin:40px auto}
table#datarows th {padding:5px 10px;background:#80B0FF;color:#FFFFFF;border:2px solid #80B0FF;width:1000px;text-align:center}
table#datarows td {padding:2px 10px;background:#FFFFFF;color:#D0D0D0;border:2px solid #80B0FF;width:1000px;text-align:left;font-style:italic}
input.err {border:2px solid #FF0000;background-color:#FFF0F0}
form.pager {display:table;margin:0 auto;padding:20px;border:2px solid #E0E0E0;border-radius:10px;background-color:#D0D0D0;text-align:left;white-space:nowrap}
form#pager1 {margin-top:40px}
form#pager2 {margin-bottom:60px}
form.pager div {display:table-cell;vertical-align:middle;padding:0 20px;white-space:nowrap}
form.pager div + div {border-left:2px solid #E0E0E0}
form.pager div.plinks {padding:0;border:0 none;font-size:14px;line-height:24px;max-width:800px;white-space:normal}
form.pager div.plinks b {display:inline-block;vertical-align:bottom;font-size:24px;line-height:21px;height:24px;overflow:hidden;color:#808080}
form.pager div.plinks a {text-decoration:none;color:black}
form.pager div.plinks a:hover {color:#0000FF;font-weight:bold}
form.pager div.plinks + div {border:0 none}
</style>
<script>
var NumPages, RecsPerPage, els1, els2, plinks1, plinks2;
function setupClick()
{
var el, n, r;
el = document.getElementById("NumPages");
el.className = ((n = (el.value >>> 0)) ? "" : "err");
el = document.getElementById("RecsPerPage");
el.className = ((r = (el.value >>> 0)) ? "" : "err");
if (n&&r) { NumPages = n; RecsPerPage = r; setupServerPage(); }
}
// This function sets up what would normally be part of the server's HTML output.
function setupServerPage()
{
var totRecs = NumPages * RecsPerPage, tbdy = document.getElementById("datarows").tBodies[0], l = tbdy.rows.length;
document.getElementById("plength1").innerHTML = document.getElementById("plength2").innerHTML = totRecs + " record" + ((totRecs===1)?"":"s") + "<br>" + NumPages + " page" + ((NumPages===1)?"":"s");
els1["pcount"].value = els2["pcount"].value = NumPages;
while (l>RecsPerPage) tbdy.deleteRow(--l);
while (l<RecsPerPage) tbdy.insertRow(l++).insertCell(0).innerHTML = "Some data...";
pageNavigate(1);
}
// This would be handled by a return trip to the server, if not using AJAX.
function pageClick(e)
{
e = e||window.event;
var s = e.target||e.srcElement, n, p, el;
if (s.tagName==="A") { n = (p = s.href).lastIndexOf("=")+1; pageNavigate(p.substring(n) >>> 0); return false; }
else if ((s.tagName!=="INPUT")||(s.type!=="submit")) return;
if (!(n = s.name)) { p = ((el = this.elements["p"]).value >>> 0); if ((p<=0)||(p>NumPages)) { el.className = "err"; return false; }}
else if (n==="p1") p = 1;
else if (n==="pprev") p = (this.elements["pcurr"].value >>> 0)-1;
else if (n==="pnext") p = (this.elements["pcurr"].value >>> 0)+1;
else if (n==="plast") p = (this.elements["pcount"].value >>> 0);
pageNavigate(p);
return false;
}
// This would also be handled by a return trip to the server, or else data records could be retrieved via AJAX.
function pageNavigate(p)
{
els1["p"].className = els2["p"].className = els1["p"].value = els2["p"].value = "";
if (p<1) p = 1; else if (p>NumPages) p = NumPages;
els1["p1"].disabled = els2["p1"].disabled = els1["pprev"].disabled = els2["pprev"].disabled = (p===1);
els1["pnext"].disabled = els2["pnext"].disabled = els1["plast"].disabled = els2["plast"].disabled = (p===NumPages);
els1["pcurr"].value = els2["pcurr"].value = p;
// if the server is handling this, insert NON-logarithmic page links here (can be just first, current, and last page).
plinks1.innerHTML = plinks2.innerHTML = logarithmicPaginationLinks(NumPages,p,"?p=");
}
// This function produces the logarithmic pagination links.
function logarithmicPaginationLinks(lastPage,matchPage,linkURL)
{
function pageLink(p, page) { return ((p===page) ? "<b>"+p+"</b>" : '<a href="'+linkURL+p+'">'+p+"</a>"); }
function pageGap(x) { if (x===0) return ""; if (x===1) return " "; if (x<=10) return " . "; if (x<=100) return " .. "; return " ... "; }
var page = (matchPage ? matchPage : 1), LINKS_PER_STEP = 5, lastp1 = 1, lastp2 = page, p1 = 1, p2 = page, c1 = LINKS_PER_STEP+1, c2 = LINKS_PER_STEP+1, s1 = "", s2 = "", step = 1, linkHTML = "";
while (true)
{
if (c1>=c2)
{
s1 += pageGap(p1-lastp1) + pageLink(p1,matchPage);
lastp1 = p1;
p1 += step;
c1--;
}
else
{
s2 = pageLink(p2,matchPage) + pageGap(lastp2-p2) + 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)
{
linkHTML += s1 + pageGap(lastp2-lastp1) + s2;
if ((lastp2>page)||(page>=lastPage)) break;
lastp1 = page;
lastp2 = lastPage;
p1 = page+1;
p2 = lastPage;
c1 = LINKS_PER_STEP;
c2 = LINKS_PER_STEP+1;
s1 = '';
s2 = '';
step = 1;
}
}
return linkHTML;
}
window.onload = function()
{
els1 = document.getElementById("pager1").elements;
els2 = document.getElementById("pager2").elements;
plinks1 = document.getElementById("plinks1");
plinks2 = document.getElementById("plinks2")
document.getElementById("pager1").onclick = document.getElementById("pager2").onclick = pageClick;
(document.getElementById("setupDiv").lastChild.onclick = setupClick)();
}
</script>
</head>
<body>
<div id="setupDiv">Select number of pages: <input type="text" id="NumPages" value="100" size="7"> and records per page: <input type="text" id="RecsPerPage" value="20" size="7"> <input type="button" value=" Go "></div>
<hr>
<form id="pager1" class="pager" method="GET"><input type="hidden" name="pcount" value=""><input type="hidden" name="pcurr" value="1">
<div>Go to page: <input type="text" name="p" size="7"> <input type="submit" value=" Go "></div>
<div><input type="submit" name="p1" value=" |< " disabled> <input type="submit" name="pprev" value=" < " disabled></div>
<div id="plinks1" class="plinks"></div>
<div><input type="submit" name="pnext" value=" > "> <input type="submit" name="plast" value=" >| "></div>
<div id="plength1"></div>
</form>
<table id="datarows"><thead><tr><th>Column Heading...</th></tr></thead><tbody></tbody></table>
<form id="pager2" class="pager" method="GET"><input type="hidden" name="pcount" value=""><input type="hidden" name="pcurr" value="1">
<div>Go to page: <input type="text" name="p" size="7"> <input type="submit" value=" Go "></div>
<div><input type="submit" name="p1" value=" |< " disabled> <input type="submit" name="pprev" value=" < " disabled></div>
<div id="plinks2" class="plinks"></div>
<div><input type="submit" name="pnext" value=" > "> <input type="submit" name="plast" value=" >| "></div>
<div id="plength2"></div>
</form>
</body>
</html>
关于user-interface - 如何对很多很多页面进行页面导航?对数页面导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7835752/
我喜欢 smartcase,也喜欢 * 和 # 搜索命令。但我更希望 * 和 # 搜索命令区分大小写,而/和 ?搜索命令遵循 smartcase 启发式。 是否有隐藏在某个地方我还没有找到的设置?我宁
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 10年前关闭。 Improve this qu
从以下网站,我找到了执行java AD身份验证的代码。 http://java2db.com/jndi-ldap-programming/solution-to-sslhandshakeexcepti
似乎 melt 会使用 id 列和堆叠的测量变量 reshape 您的数据框,然后通过转换让您执行聚合。 ddply,从 plyr 包看起来非常相似..你给它一个数据框,几个用于分组的列变量和一个聚合
我的问题是关于 memcached。 Facebook 使用 memcached 作为其结构化数据的缓存,以减少用户的延迟。他们在 Linux 上使用 UDP 优化了 memcached 的性能。 h
在 Camel route ,我正在使用 exec 组件通过 grep 进行 curl ,但使用 ${HOSTNAME} 的 grep 无法正常工作,下面是我的 Camel 路线。请在这方面寻求帮助。
我正在尝试执行相当复杂的查询,在其中我可以排除与特定条件集匹配的项目。这是一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我正在尝试执行相当复杂的查询,我可以在其中排除符合特定条件集的项目。这里有一个 super 简化的模型来解释我的困境: class Thing(models.Model) user = mod
我发现了很多嵌入/内容项目的旧方法,并且我遵循了在这里找到的最新方法(我假设):https://blog.angular-university.io/angular-ng-content/ 我正在尝试
我正在寻找如何使用 fastify-nextjs 启动 fastify-cli 的建议 我曾尝试将代码简单地添加到建议的位置,但它不起作用。 'use strict' const path = req
我正在尝试将振幅 js 与 React 和 Gatsby 集成。做 gatsby developer 时一切看起来都不错,因为它发生在浏览器中,但是当我尝试 gatsby build 时,我收到以下错
我试图避免过度执行空值检查,但同时我想在需要使代码健壮的时候进行空值检查。但有时我觉得它开始变得如此防御,因为我没有实现 API。然后我避免了一些空检查,但是当我开始单元测试时,它开始总是等待运行时异
尝试进行包含一些 NOT 的 Kibana 搜索,但获得包含 NOT 的结果,因此猜测我的语法不正确: "chocolate" AND "milk" AND NOT "cow" AND NOT "tr
我正在使用开源代码共享包在 iOS 中进行 facebook 集成,但收到错误“FT_Load_Glyph failed: glyph 65535: error 6”。我在另一台 mac 机器上尝试了
我正在尝试估计一个标准的 tobit 模型,该模型被审查为零。 变量是 因变量 : 幸福 自变量 : 城市(芝加哥,纽约), 性别(男,女), 就业(0=失业,1=就业), 工作类型(失业,蓝色,白色
我有一个像这样的项目布局 样本/ 一种/ 源/ 主要的/ java / java 资源/ .jpg 乙/ 源/ 主要的/ java / B.java 资源/ B.jpg 构建.gradle 设置.gr
如何循环遍历数组中的多个属性以及如何使用map函数将数组中的多个属性显示到网页 import React, { Component } from 'react'; import './App.css'
我有一个 JavaScript 函数,它进行 AJAX 调用以返回一些数据,该调用是在选择列表更改事件上触发的。 我尝试了多种方法来在等待时显示加载程序,因为它当前暂停了选择列表,从客户的 Angul
可能以前问过,但找不到。 我正在用以下形式写很多语句: if (bar.getFoo() != null) { this.foo = bar.getFoo(); } 我想到了三元运算符,但我认
我有一个表单,在将其发送到 PHP 之前我正在执行一些验证 JavaScript,验证后的 JavaScript 函数会发布用户在 中输入的文本。页面底部的标签;然而,此消息显示短暂,然后消失...
我是一名优秀的程序员,十分优秀!