Javascript jQuery sortColumns插件:如何使用rowspan正确排序
在这篇文章(github链接:)之后,我成功地对列进行排序,但是它在rowspan的情况下不起作用:例如,像这样的情况Javascript jQuery sortColumns插件:如何使用rowspan正确排序,javascript,jquery,html,Javascript,Jquery,Html,在这篇文章(github链接:)之后,我成功地对列进行排序,但是它在rowspan的情况下不起作用:例如,像这样的情况 Grape 3,096,671M 1,642,721M Apple 2,602,750M 3,122,020M 当我点击第二列时,它会尝试排序 Apple 2,602,750M 1,642,721M Grape 3,096,671M
Grape 3,096,671M
1,642,721M
Apple 2,602,750M
3,122,020M
当我点击第二列时,它会尝试排序
Apple 2,602,750M
1,642,721M
Grape 3,096,671M
3,122,020M
(预期结果应该是只在每行范围内排序
Grape 1,642,721M
3,096,671M
Apple 2,602,750M
3,122,020M
或
)
所以
正如您所看到的,这是不正确的,请任何jQuery大师帮助我解决这个问题。这是我的密码
var inverse = false;
function sortColumn(index){
index = index + 1;
var table = jQuery('#resultsTable');
table.find('td').filter(function(){
return jQuery(this).index() == index;
}).sortElements(function(a, b){
a = convertToNum($(a).text());
b = convertToNum($(b).text());
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
},function(){
return this.parentNode;
});
inverse = !inverse;
}
function convertToNum(str){
if(isNaN(str)){
var holder = "";
for(i=0; i<str.length; i++){
if(!isNaN(str.charAt(i))){
holder += str.charAt(i);
}
}
return holder;
}else{
return str;
}
}
所以我可以看出,如果a或b不是数字,那么就进行字符串比较,否则就进行数字比较,但我不理解
inverse ? -1 : 1 :
inverse ? 1 : -1;
测试用例
<table id="resultsTable">
<thead>
<tr>
<th>Fruit</th>
<th onclick="sortColumn(1)">Quantity</th>
<th onclick="sortColumn(2)">Rate</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="4">Grape</td>
<td>15</td>
<td>5</td>
</tr>
<tr>
<td>4</td>
<td>2</td>
</tr>
<tr>
<td>88</td>
<td>1</td>
</tr>
<tr>
<td>11</td>
<td>3</td>
</tr>
<tr>
<td rowspan="3">Melon</td>
<td>21</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
<td>0</td>
</tr>
<tr>
<td>35</td>
<td>1</td>
</tr>
<tr>
<td rowspan="6">Melon</td>
<td>24</td>
<td>5</td>
</tr>
<tr>
<td>66</td>
<td>2</td>
</tr>
<tr>
<td>100</td>
<td>4</td>
</tr>
<tr>
<td>21</td>
<td>1</td>
</tr>
<tr>
<td>65</td>
<td>3</td>
</tr>
<tr>
<td>2</td>
<td>0</td>
</tr>
</tbody>
<table>
果
量
比率
葡萄
15
5.
4.
2.
88
1.
11
3.
甜瓜
21
2.
2.
0
35
1.
甜瓜
24
5.
66
2.
100
4.
21
1.
65
3.
2.
0
考虑到问题1,请尝试以下代码:
var inverse = false;
var curRowSpan = 0;
var curIndex = 0;
var doRowSpan = false;
function sortColumn(index){
index = index + 1;
var table = jQuery('#resultsTable');
table.find('td').filter(function() {
var result = false;
// if it is a column before the sorting column, watch the rowSpan
if (curRowSpan == 0 && jQuery(this).index() < index && jQuery(this).attr("rowspan") > 1) {
curRowSpan = jQuery(this).attr("rowspan");
doRowSpan = true;
// we are not in the sorting column so we can safely continue
continue;
}
if(!doRowSpan) curIndex = index - (curRowSpan?1:0);
else curIndex = index;
if(jQuery(this).index() == curIndex) {
// we are at the sorting column
if(curRowSpan > 0) {
curRowSpan--;
}
// set this to false for the following row
doRowSpan = false;
result = true;
}
return result;
}).sortElements(function(a, b){
a = convertToNum($(a).text());
b = convertToNum($(b).text());
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
},function(){
return this.parentNode;
});
inverse = !inverse;
}
function convertToNum(str){
if(isNaN(str)){
var holder = "";
for(i=0; i<str.length; i++){
if(!isNaN(str.charAt(i))){
holder += str.charAt(i);
}
}
return holder;
}else{
return str;
}
}
这将检查a>b(按字符串或按数字),然后返回1为真,返回-1为假
现在我们插入inverse
参数,该参数应将结果反转。这意味着如果inverse==true,则1变为-1,-1变为1。在代码中,此粗体文本将用反向替换每次出现的1
-1:1
和每次出现的-1
与相反?1:-1
。这正是在生成的代码中所做的
更新:在代码中添加了
doRowSpan
,因为如果我们在
中,包含行span-td代码工作的条件,则不应调整索引:
- 包含
td
s和rowspan
的列必须全部位于表的左侧
- 这些列中的所有
td
s必须有行span
,即使它是1
- 要排序的行组由这些列中最右边的列组成(但很容易更改)
jsFiddle:
快速解释:
- 使用
rowspan查找所有td
s
- 保存这些
td
s的位置,包括左偏移
- 这些
td
s通过其原始offset
进行过滤,以仅与最右边的一起使用
- 与每个保留的
td
相关的tr
使用所需列进行排序
- 如有必要,带
rowspan
的所有td
s将最终移回其原始位置
关于问题2,我将只通过以下方式完成bartlaarhoven的回答:代码也可以按如下方式编写:
return (
(isNaN(a) || isNaN(b) ? a > b : +a > +b) ? 1 : -1
) * (inverse ? -1 : 1);
您可以很容易地看到,inverse
用于反转结果。@Newbo.O:它应该只在每个行范围内排序。我已经用预期结果更新了我的问题。仅在行范围内排序或:对每个行范围组进行排序,然后根据第一个值对组进行排序?非常感谢。当我插入你的代码时,我得到了这个javascript错误未捕获的语法错误:非法的continue语句
。你能检查一下吗,我用http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js
因为我传入索引的方式,我需要index=index+1,但是,在您的情况下,请将其取出。另外,我使用了你的代码(没有continue),但是这个表坏了,我把我用来测试的表放在我的问题中,你能看一下吗。非常感谢你。我也在调查此事。谢谢你这么说,因为我通过索引的方式,我需要index=index+1
,但是,如果是你的情况,请把它拿出来。还有,我用了你的代码,但是表坏了,我把我用来测试的表放在我的问题里,你能看一下吗。非常感谢你。我也在调查此事。谢谢我的错误,我有时把一个td
移到thead
。。。我已经更新了我的答案来解决这个问题。我还用您的数据示例创建了一个JSFIDLE(我没有放置任何CSS,所以它有点难看,但它可以工作),谢谢您,您太棒了,还有一件事。mmidle块(中间的瓜块),其排序与其他所有块的排序相反。请你看一下好吗。非常感谢:DI对代码进行了一点优化(搜索和筛选太多了),应该可以更好地处理大型表。答案已更新,因此可以处理左侧更多的行间距。仍然有条件可以使用代码,但我认为很难找到更通用的解决方案^^
var inverse = false;
var curRowSpan = 0;
var curIndex = 0;
var doRowSpan = false;
function sortColumn(index){
index = index + 1;
var table = jQuery('#resultsTable');
table.find('td').filter(function() {
var result = false;
// if it is a column before the sorting column, watch the rowSpan
if (curRowSpan == 0 && jQuery(this).index() < index && jQuery(this).attr("rowspan") > 1) {
curRowSpan = jQuery(this).attr("rowspan");
doRowSpan = true;
// we are not in the sorting column so we can safely continue
continue;
}
if(!doRowSpan) curIndex = index - (curRowSpan?1:0);
else curIndex = index;
if(jQuery(this).index() == curIndex) {
// we are at the sorting column
if(curRowSpan > 0) {
curRowSpan--;
}
// set this to false for the following row
doRowSpan = false;
result = true;
}
return result;
}).sortElements(function(a, b){
a = convertToNum($(a).text());
b = convertToNum($(b).text());
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
},function(){
return this.parentNode;
});
inverse = !inverse;
}
function convertToNum(str){
if(isNaN(str)){
var holder = "";
for(i=0; i<str.length; i++){
if(!isNaN(str.charAt(i))){
holder += str.charAt(i);
}
}
return holder;
}else{
return str;
}
}
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ? 1 : -1;
var inverse = false;
function sortColumn(index) {
var trs = $('#resultsTable > tbody > tr'),
nbRowspans = trs.first().children('[rowspan]').length,
offset = trs.first().children('[rowspan]').last().offset().left;
var tds = trs.children('[rowspan]').each(function() {
$(this).data('row', $(this).parent().index());
$(this).data('column', $(this).index());
$(this).data('offset', $(this).offset().left)
}).each(function() {
if($(this).data('offset') != offset)
return;
var rowMin = $(this).data('row'),
rowMax = rowMin + parseInt($(this).attr('rowspan'));
trs.slice(rowMin, rowMax).children().filter(function() {
return $(this).index() == index + $(this).parent().children('[rowspan]').length - nbRowspans;
}).sortElements(function(a, b) {
a = convertToNum($(a).text());
b = convertToNum($(b).text());
return (
isNaN(a) || isNaN(b) ?
a > b : +a > +b
) ?
inverse ? -1 : 1 :
inverse ? 1 : -1;
}, function() {
return this.parentNode;
});
});
var trs = $('#resultsTable > tbody > tr');
tds.each(function() {
if($(this).parent().index() != $(this).data('row'))
$(this).insertBefore(trs.eq($(this).data('row')).children().eq($(this).data('column')));
});
inverse = !inverse;
}
return (
(isNaN(a) || isNaN(b) ? a > b : +a > +b) ? 1 : -1
) * (inverse ? -1 : 1);