用于对HTML表格进行排序的jQuery插件

分享于 

17分钟阅读

Web开发

  繁體

图 1.在DateReceived上按降序排序的示例屏幕 Shot.Table

介绍

这个jQuery插件按所选列中的值对HTML进行排序。 它可以附加到 table的header 行,这样当用户单击一列 header 时,table 就会在该列上排序。 如果用户再次单击列 header,则排序将反转。 开发人员还可以基于其他事件实现排序,并将 table 恢复为它的原始顺序。 插件识别数字列和日期列并相应排序。

Background

我在一个基于浏览器的游戏游戏中,有一个 Hall的Hall Hall table。 它需要一个排序功能,所以我创建了这个插件。

限制

  • 对于使用"跨度"或者"rowspan"的表,它不能正常工作。
  • 它只识别带有数字组件和单个分隔符的日期。 默认分隔符是 '/',但可以使用可选的设置更改它。 它可以识别美国 (mm/dd/yy][yy]), 日期 (dd/mm/yy[yy]) 和欧洲日期 ([yy]yy/mm/dd). 它不关心日期是否严格有效- 这是应用程序在第一地点填充 table的任务。 它检查列中的每个日期以确定日期格式。 如果只有几个日期,而且它们是不明确的,那么它可能会得到错误的格式。 如果 table 很小,则可能需要使用可选设置来指定日期格式。
  • 如果在不看起来像数字或者日期的列中找到单元格值,它将整个列视为字符串值的一列。
  • 当表包含成千上万行时,它会。

优点

  • 添加 HTML table 到网页的能力是很容易的。
  • 它能识别日期和数字并正确排序。 有一个选项可以显式指定日期格式。
  • 排序在任何排序中保留原始的table 顺序。 这意味着它是稳定的。
  • 表可以返回到它的原始排序顺序。
  • 它不会影响 table的HTML结构。
  • 它使用jQuery和 JavaScript array 排序方法,所以它可以与大多数浏览器一起使用。
  • 在现代浏览器的a 行下,几乎是即时的。
  • 字符串排序区分大小写,但有一个选项可以替代。
  • 不需要服务器活动。

演示网页

下载中包含两个演示网页。

DemoTable.html

这个页面包含一个 table,数据看起来很真实。 参见图。 table 有一些简单的样式,让它很好。 它下面有四个按钮,用来说明插件的基本功能。 第一个让你将 table 恢复到原来的顺序。 下三个让你选择 Date Received 列的日期格式,这样你就可以验证自动日期格式选择算法。 这里有一些代码来汇总 PriceMiles 列,但这只是为了填充脚注行。

BigDemoTable.html

页包含带有 3000行数据的table。 参见图。 它用于测试所有选项和性能测试。 table 还有一些简单的样式来使它看起来很好。 在 RANDOM 上排序之前对另一列排序可以将其他列按随机顺序排序。 有一些代码可以生成 EURO NUM 列来测试可能的欧洲数字格式。

图 2.演示屏幕快照。 大 table 随机排序。

添加对网页的引用

假设你将 tablesort.js JavaScript文件放入名为 js的子文件夹中,你将在网页中添加以下行来引用 TableSort jQuery插件。

<script src="js/tablesort.js" type="text/javascript"></script>

使用代码

使用插件最简单的方法是在你的HTML table 中的每个 header 单元上附加一个单击事件来调用。 如果我们使用像这样的选择器 $('#DemoTable tr:first').children() 我们不必担心 header 行是否使用 <td> 或者 <th> 标签。 代码示例 below 假定在页面完成加载时已经存在 HTML table。 如果使用AJAX调用加载 table,或者动态构建 table,那么你将在创建 table 之后附加列 header 事件。

<script type="text/javascript">
<!--
$(document).ready(function () {
 // Select your column headers $('#DemoTable tr:first').children().click(function (e) {
 // Attach a click event to each cell to invoke the Plugin $('#DemoTable').sortByColumn($(this).text());
 });
});// --></script>

如果希望将 table 返回到它的原始状态,只需调用插件而不指定列 header。

$('#DemoTable').sortByColumn();

选项

不传递列 header 文本,你可以传入一个对象文本,指定一个扩展的选项集。 你只需要提供你想要的。 选项包括:

columnText
dateFormat
dateDelimiter
decimalDelimiter
caseSensitive
ascendingClass
descendingClass

columnText 选项必须为 header 列的第一个单元格中的文本设置 MATCH。

$('#DemoTable').sortByColumn({ columnText: $(this).text()});

dateFormat 选项可以是任何值,但只能识别 'US''UK''EU'。 默认为 '',插件将根据列的内容确定要使用的日期格式。

$('#DemoTable').sortByColumn({ columnText: $(this).text(), dateFormat: 'UK'});

可以将 dateDelimiter 选项设置为用于分隔日期组件的单个字符。 默认值为 '/'

$('#DemoTable').sortByColumn({ columnText: $(this).text(), dateDelimiter: '-'});

可以将 decimalDelimiter 选项设置为用于分隔十进制数的小数部分的单个字符。 默认值为 '.'

$('#DemoTable').sortByColumn({ columnText: $(this).text(), decimalDelimiter: ','});

可以将 caseSensitive 选项设置为 true 或者 false。 默认值为 true

$('#DemoTable').sortByColumn({ columnText: $(this).text(), caseSensitive: false});

ascendingClass 选项是类的NAME,如果它处于升序阶段,则将它的添加到当前排序列的header 单元格中。 选项是将被添加到当前排序列标题单元格中的类的名称,如果它是按降序排序的话。 在这两种情况下,默认为 ''

$('#DemoTable').sortByColumn({ columnText: $(this).text(), ascendingClass: 'redbordertop', descendingClass: 'redborderbottom'});

使用指导

插件将 table 中的数据提取到对象的array 中。 它调用 JavaScript Array.Sort 方法对 array 进行排序。 然后,它将来自已经排序的对象的array 中的数据插入到 table 中。

这与我上次使用的实现相反,它交换了DOM元素并使用了硬编码的排序算法。 它以一个冒泡排序开始,但是我把它切换到梳排序来提高性能。

插件通过将列的jQuery text() 与传递给插件的字符串值匹配来标识所单击的列。 在进行比较之前它会去除空白。 建议使用 jQuery text 方法来指定排序列。

它使用 data 方法和 _dir_ 键来存储列的当前排序状态。 值可以是 a,也可以是 d,表示降序,也可以是 undefined。 if选择器返回列标题单元,那么可以通过检查 $(this).data('_dir_')。或者 ''的来确定每个列的排序状态。

它使用以下对象来存储每行的数据。

var RowData = function () {
 this.Seq = 0;
 this.Key = '';
 this.KeyType = 0; // 0 = string, 1 = number, 2 = date (mm/dd/yy[yy]), 3 - date (dd/mm/yy[yy]), 4 - date (yy[yy]/mm/dd)this.Cells = new Array();
}

使用 Key 进行排序,而不是使用 Cells array 中的相应元素进行排序。 这使我们能够对实际的数值( 数字数) 或者upshifted字符串( 大小写不敏感字符串排序) 进行排序。

//// If first time, add original sequence number to each row for stable sortingvar rownum = 0;this.find('tr').not(':first').each(function () {
 if ($(this).data('_seq_')) {
 returnfalse;
 }
 $(this).data('_seq_', rownum);
 rownum++;
});

table 中的数据被传送到 RowData 对象的array。 Seq 属性跟踪 table的原始序列。 它通过使用 jQuery data 方法保存每行的原始序列,并使用 _seq_的键来保存。 排序比较方法通过查看 Seq 属性来解析相同的键。 这就确保了相对于 the original sort order sort在比较方法中使用 KeyKeyType。 下面是执行实际排序的代码。 如果未提供 columnText,则排序将 table 返回到它的原始顺序。

if (settings.columnText) {
 tableData.sort(function (a, b) {
 switch (a.KeyType) {
 case0: // stringif (a.Key> b.Key) {
 return sortAsc? 1 : -1;
 }
 if (a.Key <b.Key) {
 return sortAsc? -1 : 1;
 }
 break;
 case1: // Numericif (parseFloat(a.Key)> parseFloat(b.Key)) {
 return sortAsc? 1 : -1;
 }
 if (parseFloat(a.Key) <parseFloat(b.Key)) {
 return sortAsc? -1 : 1;
 }
 break;
 default: // Datevar res = DateCompare(a.KeyType, a.Key, b.Key);
 if (res == 1) {
 return sortAsc? 1 : -1;
 }
 if (res == -1) {
 return sortAsc? -1 : 1;
 }
 }
 if (a.Seq> b.Seq) {
 return1;
 }
 return -1;
 });
}else {
 tableData.sort(function (a, b) {
 if (a.Seq> b.Seq) {
 return1;
 }
 return -1;
 });
}

请注意,Key 需要对 KeyType 进行 MATCH。 在数字字段中,可以使用正则表达式将 Key的实际数值减少为它的实际数值。 它在排序之前,而不是在比较例程中,来减少正则表达式性能命中。

完成排序后,数据从 RowData 对象的array 复制回 HTML table。 它跳过第一行和所有脚注行。

rowX = -1;this.find('tr').not(':first').each(function () {
 if (!$(this).parent().is('tfoot')) {
 rowX++;
 var rowData = tableData[rowX];
 $(this).data('_seq_', rowData.Seq);
 colX = -1;
 $(this).children().each(function () {
 colX++;
 $(this).text(rowData.Cells[colX]);
 });
 }
});

确定日期格式

基本思想是年可以有任何值,天只能在范围 1,而月份只能在范围 1的范围内。 插件扫描任何包含由 dateDelimiter 分隔的三个整数的列。 它计算它找到的有效日期和月份数,并从结果中确定日期格式。 在一个足够大的示例中,你将得到一个位置,其中没有字段超过 12,而没有字段超过 31. 这将告诉你哪些字段代表日。月和年。 因为某种格式的日期同样有效,所以它可能并不总是有效。 但很有可能 ! 如果知道日期格式,则可以使用 dateFormat 选项显式设置。

处理数字

数字的书写方式因国家而异。 在英语语言国家,句点用作小数分隔符和逗号作为数字组分隔符。 在欧洲国家,逗号可以用作十进制分隔符和空格或者周期作为数字组分隔符。 要确保正确排序,可以将 decimalDelimiter 设置为选项。 数字组分隔符由只允许数字。减号和当前小数分隔符的正则表达式去除。 ( var numExp = new RegExp('[^0-9' + settings.decimalDelimiter + '-]+', 'g'); )。

这是将小数分隔符设置为逗号的选项。

$('#DemoTable').sortByColumn({ columnText: $(this).text(), decimalDelimiter: ','});

图 3。"接收日期"转换为'eu',用逗号十进制分隔符排序。

为什么没有标志符号?

某些 table 排序系统使用列 header 中的标志符号来指示排序的状态。 如果没有标志符号空间,或者添加一个更改列的宽度,则可能会出现问题。 插件通过允许开发人员创建可以应用到单元格的CSS类来指示它们是否当前按升序或者降序排序,从而保留了对开发人员的排序方法。 在 DemoTable.html 中,开发人员选择使用顶红色边框来表示升序和底部红色边框,以指示降序。 这似乎工作得很好。 下面是将它们传递给插件的类和代码。

.ascending {
 border-top: solid 3px red;
}
...
.descending {
 border-bottom: solid 3px red;
}
...
$('#DemoTable th').click(function (e) {
 $('#DemoTable').sortByColumn({ columnText: $(this).text(),
 ascendingClass: 'ascending',
 descendingClass: 'descending'});
 });

效率

通过运行 Windows 10 ( 64位 ) 和i7-3770处理器和Intel处理器 @,在戴尔XPS计算机上进行性能测试。 它使用了 3000行和 8列的BigDemoTable.html

BrowserVersionFastest时间( 秒) 最慢的时间( 秒)
Google Chrome50.0.2661.75 m0.971.32
Mozilla Firefox45.0.20.750.85
微软边缘25.10586.0.03.664.10
微软 IE11.212.10586.03.894.19

Firefox 在 Chrome edges,而 Microsoft siblings显著降低。 注意,3000行相当于 50到 100页面下跌,这取决于监视器分辨率。 大多数应用程序不会向浏览器交付这样的数据量。

创建一个JQuery插件

It intimidating但并不是那么难。 基本内容是在这个站点和这个代码项目文章中的封面。

下载内容

dowload包含两个演示页面和一个名为 js的子文件夹,其中包含TableSort插件( tablesort.js ) 和一个缩小版本( tablesort.min.js )。

Points of Interest

  • 创建一个无需太多编码工作量的jQuery插件是相对容易的。
  • 处理各种国际格式和日期使通用排序插件更复杂。
  • 内部 Array.Sort() 方法是快速的。 分析显示大部分的CPU时间是从一个 html table 提取数据并返回排序数据。

历史记录

代码项目的第一个版本


plugin  tab    jquery-plugin  sort  tables  
相关文章