我有一个html表,我用javascript排序。该表可以轻松拥有超过+1000行。
这是我目前所拥有的,html看起来与此类似:
<div id="mycollection" class="table">
<div class="title">
<div class="A">id</div>
<div class="B">name</div>
<div class="C">total</div>
<div class="D">cost</div>
</div>
<div class="row">
<div class="A">1</div>
<div class="B">Jack</div>
<div class="C">101</div>
<div class="D">$5</div>
</div>
<div class="row">
<div class="A">5</div>
<div class="B">Zoe</div>
<div class="C">5</div>
<div class="D">$10</div>
</div>
<div class="row">
<div class="A">3</div>
<div class="B">Adam</div>
<div class="C">21</div>
<div class="D">$7</div>
</div>
</div>
我的javascript看起来像这样:
function testSort(s) {
var column = s;
var parent = document.getElementById('mycollection');
var rows = parent.children; // NodeList
rows = Array.prototype.slice.call(rows, 0); // change NodeList to array
var top = rows.shift(); // remove title row
// sort
rows.sort(function(a, b) {
if(a.getElementsByClassName(column)[0].textContent < b.getElementsByClassName(column)[0].textContent) return -1;
if(a.getElementsByClassName(column)[0].textContent > b.getElementsByClassName(column)[0].textContent) return 1;
return 0;
});
// recreate div
parent.innerHTML = ''; // clear
parent.appendChild(top); // add title row
for(var i=0, l=rows.length; i<l; i++) { // add rows
parent.appendChild(rows[i]);
}
}
testSort('D');
我在这里设置了一个jsfiddle:
http://jsfiddle.net/rotaercz/f6p377au/
*另外有没有办法让C和D列正确排序?它目前只按字母顺序排序。
答案 0 :(得分:3)
作为一般规则,从{em>里面调用DOM访问或(!!)操作工具.sort()
比较器功能是避免所有可能的努力。在这种情况下,您应该通过节点单次传递并提取文本内容一次。这将使你的排序更快,更快,特别是当行数超过几行时。
以下是如何执行此操作的示例:
function testSort(s) {
var column = s;
var parent = document.getElementById('mycollection');
var rows = parent.children; // NodeList
rows = Array.prototype.slice.call(rows, 0); // change NodeList to array
var top = rows.shift(); // remove title row
var extracted = rows.map(function(row) {
return {
text: row.getElementsByClassName(column)[0].textContent,
row: row
};
});
// sort
extracted.sort(function(a, b) {
if(a.text < b.text) return -1;
if(a.text > b.text) return 1;
return 0;
});
// recreate div
parent.innerHTML = ''; // clear
parent.appendChild(top); // add title row
for(var i=0, l=extracted.length; i<l; i++) { // add rows
parent.appendChild(extracted[i].row);
}
}
在排序之前,该代码将rows
数组转换为另一个数组,一个由普通对象组成。每个对象都有从列中提取的文本和一个返回DOM节点的引用。
sort函数因此可以直接引用字符串而无需调用.getElementsByClassName()
。
如果您有100行,那么可能会将几个百次次调用保存到.getElementsByClassName
;对于1000行,它将节省数千个。
关于按内容的数值排序,您必须检测文本看起来是数字(按照您喜欢的任何标准)并隐式转换它,或者允许传递额外的参数表明应该这样做。我个人会去第二条路线,并改变功能签名:
function testSort(s, numeric) {
然后提取数组将以类似方式构建,但现在它被告知要转换为数字:
var extracted = rows.map(function(row) {
var sv = row.getElementsByClassName(column)[0].textContent;
return {
text: numeric ? +sv.replace(/\D/g, '') : sv,
row: row
};
});
现在,当您传入数字标志时,排序比较器功能中的比较将正常工作:
testSort("D", true);
答案 1 :(得分:0)
处理大量元素时的一个常见问题是不断重绘DOM。为了最大限度地减少这种情况并使其更快,您可以克隆您希望操作的DOM部分,进行更改然后进行替换,或者您可以创建表示元素的字符串并仅将结束字符串追加一次。
示例:
var urlsDOM = '';
resultSet.forEach(function(result){
urlsDOM += '<li>' + result.someProperty + '</li>';
});
同时检查此插件:TableSorter