虽然网页设计社区逐渐不再使用表格来布置页面结构,但表格确实有一个至关重要的用途,它们的原始用途。它们用于布置表格数据。例如,想象一张员工表。
Name | 薪水 | 延期 | 开始日期 | 开始日期(美国) |
---|---|---|---|---|
博客,弗雷德 | $12000.00 | 1353 | 18/08/2003 | 08/18/2003 |
特维,凯文 | $191200.00 | 2342 | 02/05/1979 | 05/02/1979 |
姆博戈,阿诺德 | $32010.12 | 2755 | 09/08/1998 | 08/09/1998 |
莎士比亚,比尔 | $122000.00 | 3211 | 12/11/1961 | 11/12/1961 |
莎士比亚,哈姆内特 | $9000 | 9005 | 01/01/2002 | 01/01/2002 |
菲茨,马文 | $3300 | 5554 | 22/05/1995 | 05/22/1995 |
很简单。但是,如果您在客户端应用程序中看到该表,您会希望能够单击标题并对表进行排序,不是吗?我知道当你做不到的时候它总是让我烦恼。相当多的 Web 应用程序确实允许这样做。他们中的大多数,通过向关系数据库(一个非常适合表格数据的环境)提交 SQL 查询来提取这些数据,通过重新提交整个页面并使用类似 ordercolumn=4
URL 的内容,然后ORDER BY
在他们的 SQL 查询中添加一个子句来实现这一点从指定列排序的数据库中返回数据。
重新提交页面?只是为了对我们已有的数据进行排序?我相信我们可以做得更好。
Name | 薪水 | 延期 | 开始日期 | 开始日期(美国) ▾ |
---|---|---|---|---|
莎士比亚,比尔 | $122000.00 | 3211 | 12/11/1961 | 11/12/1961 |
特维,凯文 | $191200.00 | 2342 | 02/05/1979 | 05/02/1979 |
菲茨,马文 | $3300 | 5554 | 22/05/1995 | 05/22/1995 |
姆博戈,阿诺德 | $32010.12 | 2755 | 09/08/1998 | 08/09/1998 |
莎士比亚,哈姆内特 | $9000 | 9005 | 01/01/2002 | 01/01/2002 |
博客,弗雷德 | $12000.00 | 1353 | 18/08/2003 | 08/18/2003 |
如您所见,上表现在具有可单击的标题,可按单击的列对表进行排序。请注意数字和日期列是如何正确排序的,而不是按字母数字排序。
这不是一个新技巧,使用 DOM 对表进行排序。但是,这个迷你库有两个不错的属性;首先,不出所料,它遵循我的不显眼的 DHTML 原则,如下所示。第二个是,如上所述,它知道如何对各种不同的数据类型进行排序,并且它自己解决它们——你不必告诉它。
现在,如何使用它。要使您选择的表可排序,需要三个步骤:
<script src="sorttable.js"></script>
<table class="sortable">
请注意,该库的 JavaScript 文件称为 sorttable
(两个 T),但您添加到表中的类是 sortable
(一个 T)。这就是你所需要的。您的表格现在可以通过单击标题进行列排序。为了美观起见,您可能希望将以下样式添加到您的样式表中,或者在此基础上制作一些您自己的样式:
/* Sortable tables */
table.sortable thead {
background-color:#eee;
color:#666666;
font-weight: bold;
cursor: default;
}
这是 sorttable 的第 2 版,于 2007 年 4 月发布,此后不断进行调整。如果您使用的是旧版本,您可能会发现更新很有用;v2 有许多新功能,应该完全向后兼容。
您可能不需要这里的位。Sorttable 旨在无需配置,无需摆弄。拿着它并使用它。如果您需要它比默认情况下做的更多,那么回到这里阅读这部分。
一旦你在运行时向页面添加了一个新表(例如,通过执行 Ajax 请求来获取内容,或者通过使用 JavaScript 动态创建它),获取对它的引用(可能使用 var newTableObject = document.getElementById(idOfTheTableIJustAdded)
或类似),然后执行这:
sorttable.makeSortable(newTableObject);
如果您在表格底部有一个“总计”行,您希望将其 保留在表格底部(而不是排序),则将其添加到<tfoot>
表格中的一个部分(无论如何您都应该这样做) ,根据 HTML 规范)。因此,您的表格应如下所示:
<table class="sortable">
<thead>
<tr><th>Person</th><th>Monthly pay</th></tr>
</thead>
<tbody>
<tr><td>Jan Molby</td><td>£12,000</td></tr>
<tr><td>Steve Nicol</td><td>£8,500</td></tr>
<tr><td>Steve McMahon</td><td>£9,200</td></tr>
<tr><td>John Barnes</td><td>£15,300</td></tr>
</tbody>
<tfoot>
<tr><td>TOTAL</td><td>£45,000</td></tr>
</tfoot>
</table>
请注意对表格进行排序时如何将 TOTAL 行留在底部。
人 | 月薪 |
---|---|
全部的 | £45,000 |
简·莫尔比 | £12,000 |
史蒂夫·尼科尔 | £8,500 |
史蒂夫麦克马洪 | £9,200 |
约翰·巴恩斯 | £15,300 |
可以在可排序表的列标题中显示一个符号以指示该表是可排序的。像这样的东西:
系列 | 满分十分 |
---|---|
原创系列 | 7 |
下一代 | 9 |
DS9 | 5 |
去旅行 | 2 |
企业 | 3 |
为此,请在样式表中添加一些 CSS:
table.sortable th:not(.sorttable_sorted):not(.sorttable_sorted_reverse):not(.sorttable_nosort):after {
content: " \25B4\25BE"
}
请注意,这需要支持 CSS 生成的内容,这需要现代风格的浏览器。当然,您可以将生成的内容更改为您想要的任何内容。
您可能有一些数据确实按顺序排列但未由 sorttable 识别。解决此问题的方法是使用自定义排序键。以一列拼写出来的数字为例。通常, sorttable 在这里不起作用。它将拼出的数字视为字符串,因此将按字母顺序对数字进行排序,即五、四、一、三、二。为了解决这个问题,您可以在表格中的单元格上指定一个sorttable_customkey
属性,并且 sorttable 将在对表格进行排序时使用该属性的内容而不是单元格本身中的文本。因此,例如,您的表格可能如下所示:
<table class="sortable">
<tr><th>Number (spelled)</th><th>Person</th></tr>
<tr><td sorttable_customkey="2">two</td><td>Jan</td></tr>
<tr><td sorttable_customkey="3">three</td><td>Bruce</td></tr>
<tr><td sorttable_customkey="1">one</td><td>Steve</td></tr>
</table>
请注意,单击下表中的“数字(拼写)”列会按正确的一、二、三顺序对其进行排序。
数字(拼写) | 人 |
---|---|
二 | 简 |
三 | 布鲁斯 |
一 | 史蒂夫 |
您几乎可以通过指定自定义排序键来解决您在 sorttable 的自动列输入方面遇到的任何问题。
Sorttable 计算出列的类型,以便确定如何对它们进行排序(例如,数字排序不同于字母)。有时,它可能会出错。如果是这样,您可以显式指定列的类型,这将覆盖 sorttable 的评估。要指定类型,请在该列的标题行 中添加一个类。可用的列类型为、 、和。后两个用于日期,但不太可能有用,因为如果 sorttable 无法自动识别日期,那么排序无论如何都不会工作。sorttable_columntype
numeric
alpha
ddmmmmdd
因此,例如,如果您有一个“零件号”列,您希望将其视为数字,那么您可以像这样处理您的表格:
<table class="sortable">
<tr>
<th class="sorttable_numeric">Part number</th><th>Part name</th>
</tr>
<tr>
<td>111-A5</td><td>Three-eighths Gripley</td>
</tr>
<tr>
<td>31337-H4X0R</td><td>Computer system intrusion toolkit</td>
</tr>
</table>
请记住:您可能不需要这样做。您不太可能需要“强制”排序表来识别列类型。您可能还想使用上面的自定义排序键进行调查,作为实现目标的更好方法。
sorttable 的一个常见问题是如何使其处理自定义日期格式。Sorttable 将尝试以您添加的任何格式理解日期,但有时需要帮助。如上所述,这样做的方法是使用自定义排序键。如果您有这样的表格单元格:
<td>February 11th 2008, 1.19pm</td>
通过添加 YYYYMMDDHHMMSS 格式的自定义排序键来更改它们:
<td sorttable_customkey="20080211131900">February 11th 2008, 1:19pm</td>
自定义键中日期的 YYYYMMDDHHMMSS 格式将正确排序,并且 sorttable 将使用自定义键中的信息而不是表格单元格本身中的信息。
另一个常见的请求是 sorttable 对 IP 地址进行排序。这可能会在 sorttable v3 中自动处理,但在此之前,您可以使用自定义排序键来解决它。将具有 IP 地址的单元格从 更改<td>1.2.191.17</td>
为 <td sorttable_customkey="001.002.191.017">1.2.191.17</td>
; 也就是说,添加 IP 地址的自定义键,但 IP 中的每个八位字节长度为三位数,必要时用零填充。然后 Sorttable 将正确排序此列。
IP地址 | 服务器名称 |
---|---|
205.17.31.161 | 血沉 |
192.168.0.1 | 山德 |
75.244.151.2 | 贾尔斯 |
4.8.16.196 | 柳 |
默认情况下,Sorttable 进行不稳定排序。这意味着它不维护这些行在排序列中具有相同键的行的顺序。维基百科有 更多关于稳定排序的内容。如果这是一个问题,并且您需要排序稳定,您可以通过对 sorttable.js 进行微小的编辑来实现。编辑文件并找到以下行:
/* If you want a stable sort, uncomment the following line */
//sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
/* and comment out this one */
row_array.sort(this.sorttable_sortfunction);
并更改它们,以便取消注释该 Shaker_sort 行:
sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
//row_array.sort(this.sorttable_sortfunction);
排序现在将是稳定的。但是,它会慢很多 (稳定排序的时间是不稳定排序的八倍),这就是默认情况下不启用它的原因。
Sorttable 默认对英文文本进行排序。如果您正在对具有不同字母顺序的不同语言的文本进行排序(特别是,如果您看到重音字符没有按您期望的方式排序),那么您可以告诉 sorttable 以该语言排序的页面。包含后 sorttable.js
,添加
<script>sorttable.sort_alpha = function(a,b) { return a[0].localeCompare(b[0]); }</script>
sorttable 将开始使用浏览器和页面语言的排序顺序进行排序。(默认情况下不会这样做,因为localeCompare
排序虽然绝对是正确的做法,但比字符串比较慢得多。)如果您想强制 sorttable 以特定语言的排序顺序排序而不管浏览器如何,您可以在通话中添加语言代码 ;在这里,我们强制比较是芬兰语:
<script>sorttable.sort_alpha = function(a,b) { return a[0].localeCompare(b[0], 'fi' ); }</script>
有时您想通过自己的 JavaScript 代码告诉表格进行排序。这是故意尴尬的,因为您不应该这样做,并且您需要确保您有最新版本的 sorttable.js 来执行此操作(从该站点下载),但它是可行的。称呼
var myTH = document.getElementsByTagName("th")[0];
sorttable.innerSortFunction.apply(myTH, []);
请参阅下面的示例表和按钮。
Name | 车 |
---|---|
斯图尔特·兰格里奇 | 日产 Juke |
杰里米克拉克森 | 奔驰 CLK 黑色 |
佩内洛普进站 | 粉红猫 |
蚂蚁山暴徒 | 突突突 |
按“名称”列排序 按“汽车”列排序
您可以隐藏 sorttable 的图标并将您自己的图标与 CSS 一起使用,如下所示:
table.sortable th::after, th.sorttable_sorted::after, th.sorttable_sorted_reverse::after {
content: " ";
display: inline-block;
width: 24px;
height: 24px;
}
th.sorttable_sorted::after {
background: url(my-sorted-icon.png);
background-size: contain;
}
th.sorttable_sorted_reverse::after {
background: url(my-sorted-reversed-icon.png);
background-size: cover;
}
#sorttable_sortfwdind, #sorttable_sortrevind { display: none; }
Name | 薪水 | 延期 | 开始日期 | 开始日期(美国) |
---|---|---|---|---|
博客,弗雷德 | $12000.00 | 1353 | 18/08/2003 | 08/18/2003 |
特维,凯文 | $191200.00 | 2342 | 02/05/1979 | 05/02/1979 |
姆博戈,阿诺德 | $32010.12 | 2755 | 09/08/1998 | 08/09/1998 |
莎士比亚,比尔 | $122000.00 | 3211 | 12/11/1961 | 11/12/1961 |
莎士比亚,哈姆内特 | $9000 | 9005 | 01/01/2002 | 01/01/2002 |
菲茨,马文 | $3300 | 5554 | 22/05/1995 | 05/22/1995 |
如果您希望某些列标题不可点击,这意味着您的用户将无法通过这些列重新访问表格,然后添加 class="sorttable_nosort"
到<th>
列标题。观察这里的“腿数”列是如何不可排序的。
Name | 团队 | 腿数 |
---|---|---|
莫尔比,一月 | 利物浦 | 2 |
休斯,马克 | 曼联 | 2 |
尼科尔,史蒂夫 | 利物浦 | 2 |
阿迪尔斯,奥西 | 托特纳姆热刺足球俱乐部 | 2 |
大象内莉 | 伦敦动物园联合 | 4 |
尼古拉斯,查理 | 兵工厂 | 2 |
很多人问,“如何在第一次加载页面时让 sorttable 对表格进行排序?” 答案是:你没有。Sorttable 是关于在不刷新页面的情况下更改从服务器提供的 HTML。当页面首次从服务器提供时,无论如何您都必须等待它被提供。因此,如果您希望在第一次显示页面时对表格进行排序,请按排序顺序提供表格。表通常来自数据库;使用 SQL 中的 ORDER BY 子句按排序顺序从数据库中获取数据。任何涉及您在页面加载后立即运行 sorttable 的解决方案(即,没有用户输入)都是错误的解决方案。
(但是,如果您真的想要,请参阅根据您自己的代码对表格进行排序。)
使 sorttable 首先按降序而不是升序对列进行排序需要编辑 sorttable.js。找到这一行:
row_array.sort(this.sorttable_sortfunction);
在它之后,添加一个新行:
row_array.reverse();
使 sorttable 对列进行不区分大小写的排序(因此大写和小写字母一起排序)需要编辑 sorttable.js。找到以下行:
sort_alpha: function(a,b) {
if (a[0]==b[0]) return 0;
if (a[0]<b[0]) return -1;
return 1;
},
并将它们更改为
sort_alpha: function(a,b) {
if (a[0].toLowerCase()==b[0].toLowerCase()) return 0;
if (a[0].toLowerCase()<b[0].toLowerCase()) return -1;
return 1;
},
一个相当常见的请求是在表的左侧有一列,其中包含每一行的“行号”(因此第一行是“1”,第二行是“2”等等),当表已排序。
无需使用某些高级 CSS 进行排序,这是可能的。添加到您的样式表:
table.sortable tbody {
counter-reset: sortabletablescope;
}
table.sortable thead tr::before {
content: "";
display: table-cell;
}
table.sortable tbody tr::before {
content: counter(sortabletablescope);
counter-increment: sortabletablescope;
display: table-cell;
}
并且您的可排序表现在将在支持此技术的浏览器中具有左侧的“行号”列,这基本上是从 IE8 开始的所有内容。
一个简单的实时示例(请记住,“行号”列不会在非常旧的浏览器中显示)
Name | 年龄 |
---|---|
玛士撒拉 | 969 |
以利亚·斯诺 | 100 |
秀兰邓波尔 | 10 |
乔治伯恩斯 | 91 |
罗宾逊夫人 | 40 |
想要在表格中添加背景条纹(“斑马条纹”)并让这些条纹即使在排序后也能正常工作是很常见的。
无需使用某些高级 CSS 进行排序,这是可能的。添加到您的样式表:
table.sortable tbody tr:nth-child(2n) td {
background: #ffcccc;
}
table.sortable tbody tr:nth-child(2n+1) td {
background: #ccffff;
}
并且您的可排序表现在将在支持此技术的浏览器中出现斑马条纹,这基本上是从 IE9 及以后的所有内容。
一个简单的实时示例(请记住,条带化不会在非常旧的浏览器中显示)
团队 | 颜色 |
---|---|
伍尔弗汉普顿 | 橘子 |
兵工厂 | 红色的 |
利物浦 | 红色的 |
英国 | 白色的 |
您可以拥有一个带有可滚动正文的可排序表,尽管它需要您为列指定明确的宽度。 有关工作示例,请参见 http://jsbin.com/enotac/2 ;可滚动主体的 CSS 灵感来自Terence Ordona。
公司 | 领导 |
---|---|
苹果 | 蒂姆·库克 |
Kryogenix 咨询 | 斯图尔特·兰格里奇 |
处女 | 理查德布兰森 |
典范 | 马克沙特尔沃思 |
路易威登 | 路易威登 |
谷歌 | 拉里佩奇 |
甲骨文 | 拉里·埃里森 |
阿玛尼 | 乔治·阿玛尼 |
法拉利 | 恩佐·法拉利 |
当表格在下方滚动时,您还可以让表格的标题贴在页面顶部。请参阅Adrian Roselli 的文章以解释如何在现代浏览器中执行此操作。
您可以从书签加载排序表。一个使当前页面上的所有表都可排序的简单示例是make tables sortable。将其拖到您的书签栏,然后在页面上单击它将使该页面上的所有表格可排序。