相信很多人在使用tablesorter的时候都发现了在中文列排序的时候,并没有按照汉语首字母顺序排列。我在网上查找了解决方法,基本上都是老版本的方法。对于全新的2.0版本是没有作用的。后来,我又仔细地看了源代码,发现完美解决的办法,现在分享给大家:
1.首先,打开“jquery.tablesorter.js”这个文件,定位到“multisort(table, sortList, cache){... ...}”这个函数,解释两个细节:
细节一:函数中定义了一个变量“dynamicExp”,这个变量以字符串的形式保存了一个函数名为“sortWrapper”的函数的代码片段。然后“sortWrapper”在函数末尾以参数的形式传递给了“sort(param)”。如下:
cache.normalized.sort(sortWrapper);
就是说“dynamicExp”是一个动态更新的函数。
var s = (table.config.parsers[c].type == "text") ? ((order == 0) ? makeSortFunction("text", "asc", c) : makeSortFunction("text", "desc", c)) : ((order == 0) ? makeSortFunction("numeric", "asc", c) : makeSortFunction("numeric", "desc", c));
上述代码中,“makeSortFunction(type, direction, index)”函数即为我们要关注的函数。我们关注的前两个参数(type和direction)的意义及各态如下表:
type | direction | |
---|---|---|
text | 被排序对象为字符串 | - |
numeric | 被排序对象为数字 | - |
asc | - | 降序 |
desc | - | 升序 |
首先,将上面细节二里面的s变量的定义做如下修改:
var s = (table.config.parsers[c].type == "text") ? ((order == 0) ? makeSortFunction("text", "asc", c, table) : makeSortFunction("text", "desc", c, table)) : ((order == 0) ? makeSortFunction("numeric", "asc", c, table) : makeSortFunction("numeric", "desc", c, table));
我在“makeSortFunction(type, direction, index)”函数的参数中新增了一个“table”。用来读取“table”对象config属性的sortLocaleCompare值,如果此值被赋值为“true”则使用汉语排序规则,如果被赋值为“false”则使用英文排序规则。
然后,去改“makeSortFunction(type, direction, index, table)”函数:
原函数:
function makeSortFunction(type, direction, index, table) {
var a = "a[" + index + "]",
b = "b[" + index + "]";
if (type == 'text' && direction == 'asc') {
return "(" + a + " == " + b + "
? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: (" + a + " < " + b + ") ? -1 : 1 )));";
} else if (type == 'text' && direction == 'desc') {
return "(" + a + " == " + b + "
? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: (" + b + " < " + a + ") ? -1 : 1 )));";
} else if (type == 'numeric' && direction == 'asc') {
return "(" + a + " === null && " + b + " === null)
? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: " + a + " - " + b + "));";
} else if (type == 'numeric' && direction == 'desc') {
return "(" + a + " === null && " + b + " === null)
? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: " + b + " - " + a + "));";
}
};
修改后:
function makeSortFunction(type, direction, index, table) {
var a = "a[" + index + "]",
b = "b[" + index + "]";
if (type == 'text' && direction == 'asc') {
if(table.config.sortLocaleCompare){
return b+".localeCompare("+ a + ");";
}
else{
return "(" + a + " == " + b + "
? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: (" + a + " < " + b + ") ? -1 : 1 )));";
}
} else if (type == 'text' && direction == 'desc') {
if(table.config.sortLocaleCompare){
return a+".localeCompare("+ b + ");";
}
else{
return "(" + a + " == " + b + " ? 0
: (" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: (" + b + " < " + a + ") ? -1 : 1 )));";
}
} else if (type == 'numeric' && direction == 'asc') {
return "(" + a + " === null && " + b + " === null)
? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: " + a + " - " + b + "));";
} else if (type == 'numeric' && direction == 'desc') {
return "(" + a + " === null && " + b + " === null)
? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: " + b + " - " + a + "));";
}
};
可以看到,我在type是“text”的情况下,加了一个判定,我用“if...else...”写是为了大家看的时候不费劲,当然也可以按照源代码的那种铺陈的形式,写成“..?...:”的形式。这个判定的作用是,如果排序规则是中文(sortLocaleCompare==true),则使用Jquery默认包含的localeCompare函数进行排序,否则再用英文排序规则。用“...?...:”书写的形式如下:
function makeSortFunction(type, direction, index, table) {
var a = "a[" + index + "]",
b = "b[" + index + "]";
if (type == 'text' && direction == 'asc') {
return table.config.sortLocaleCompare
?b+".localeCompare("+ a + ");"
:"(" + a + " == " + b + "
? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: (" + a + " < " + b + ") ? -1 : 1 )));";
} else if (type == 'text' && direction == 'desc') {
return table.config.sortLocaleCompare
?a+".localeCompare("+ b + ");"
: "(" + a + " == " + b + "
? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: (" + b + " < " + a + ") ? -1 : 1 )));";
} else if (type == 'numeric' && direction == 'asc') {
return "(" + a + " === null && " + b + " === null)
? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: " + a + " - " + b + "));";
} else if (type == 'numeric' && direction == 'desc') {
return "(" + a + " === null && " + b + " === null)
? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY
: (" + b + " === null ? Number.NEGATIVE_INFINITY
: " + b + " - " + a + "));";
}
};
以上代码看起来是否简洁很多呢?O(∩_∩)O~
至于sortLocaleCompare值,可以在“jquery.tablesorter.js”文件的“defaults”属性中找到。如下:
this.defaults = {
cssHeader: "header",
cssAsc: "headerSortUp",
cssDesc: "headerSortDown",
cssChildRow: "expand-child",
sortInitialOrder: "asc",
sortMultiSortKey: "shiftKey",
sortForce: null,
sortAppend: null,
sortLocaleCompare: true,
textExtraction: "simple",
parsers: {}, widgets: [],
widgetZebra: {
css: ["even", "odd"]
}, headers: {}, widthFixed: false,
cancelSelection: true,
sortList: [],
headerList: [],
dateFormat: "us",
decimal: '/\.|\,/g',
onRenderHeader: null,
selectorHeaders: 'thead th',
debug: false
};
O了,是不是很简单呢?希望你的问题能够早日解决~!