我有一个非常大的表格(5000 多行),用户可以选择删除单元格并将其下方的单元格向上移动...
see this作为该表的实际示例
表格是这样的
<table border="1" id="align"><table id="section0"><tr id="0">
<td><input type="checkbox" id="s0" value="s0" onclick="add(this);"></td>
<td id="num_s0">0</td>
<td id="seg_s0">Sixty-fifth session</td>
<td id="seg_t0">65 session</td>
<td id="num_t0">0</td>
<td><input type="checkbox" id="t0" value="t0" onclick="add(this);"></td>
</tr>
<tr id="797">
<td><input type="checkbox" id="s797" value="s797" onclick="add(this);"></td>
<td id="num_s797">797</td>
<td id="seg_s797">—</td>
<td id="seg_t797">achievements</td>
<td id="num_t797">797</td>
<td><input type="checkbox" id="t797" value="t797" onclick="add(this);"></td>
</tr><tr id="798">
<td><input type="checkbox" id="s798" value="s798" onclick="add(this);"></td>
<td id="num_s798">798</td>
<td id="seg_s798">—</td>
<td id="seg_t798">مؤشرات الإنجاز</td>
<td id="num_t798">798</td>
<td><input type="checkbox" id="t798" value="t798" onclick="add(this);"></td>
</tr>
</table>
</table>
因此,当您选中任何行中的复选框时,它应该调用函数 add
function add(el)
{
var el_type=el.id[0];
var el_number=Number(el.id.slice(1));
if (el.checked==true){
var row_obj=item(el.id).parentNode.parentNode
var row_number=row_obj.id
var next_row_obj=row_obj.nextSibling
var section_table_obj=item(el.id).parentNode.parentNode.parentNode.parentNode
alert('row number: '+row_number+ 'table id: '+section_table_obj.id+ ' Next row: '+row_obj.nextSibling.id)
while (next_row_obj){
new_next_row_obj=next_row_obj.nextSibling
next_row_obj.innerHTML=new_next_row_obj.innerHTML
next_row_obj=new_next_row_obj
}
}
因此,一旦您选择任何复选框,该函数就会检索其父行,然后更新下面的行。不过,我有一些问题:
1- 浏览器会等到循环结束才更新后面的每一行,因此每个操作需要很长时间(5-10 秒)才能完成。我想在每次迭代后更新表格。
2-我不想向下移动整行,而只想向下移动所选的一侧(左侧三个或右侧三个)。那么我如何在所选行中选择特定的 TD 并根据相应的 TD 更新其innerHTML下面的行(反之亦然)?
3-我希望最终能够选择多个单元格并删除它们,因此我不想根据以下同级的内容更新行,而是根据偏移量 n 行之后的同级更新行。 ..我该怎么做?
(我是否应该更好地将这些问题分成三个单独的问题?)
最佳答案
当您选中复选框时,我真的不明白您想要做什么。看来您正在删除它下面的行,但是以一种奇怪的方式。每次选中复选框时,都会删除底部一行的内容。只删除一行而不是更新表中的每一行不是更容易吗?
无论如何,如果您想要“看到”行更新,则必须拆分更新循环,以便为浏览器提供渲染时间。实现此目的的最佳方法是使用 requestAnimationFrame,尽管 IE9 及更低版本不支持它。 基本上,requestAnimationFrame 的行为与 setTimeout 类似(如果您需要支持较旧的浏览器,则可以使用 setTimeout),但它不是在一段时间后执行,而是在浏览器下次需要渲染帧时执行(与垂直同步同步)。
所以你应该创建一个像这样的函数:
var row_obj = null;
var next_row_obj= null;
var new_next_row_obj;
function add(this) {
var el_type=el.id[0];
var el_number=Number(el.id.slice(1));
if (el.checked==true){
row_obj=item(el.id).parentNode.parentNode
var row_number=row_obj.id
next_row_obj=row_obj.nextSibling;
if (next_row_obj) requestAnimationFrame(processChunk);
}
}
function processChunk() {
var i = 0;
while (next_row_obj && i < 10){
new_next_row_obj=next_row_obj.nextSibling
next_row_obj.innerHTML=new_next_row_obj.innerHTML
next_row_obj=new_next_row_obj;
i++;
}
//if there are more elements, call it again.
if (new_next_row_obj) requestAnimationFrame(processChunk);
else {
row_obj = next_row_obj = new_next_row_obj = null;
}
}
使用此代码,将更新十行,然后浏览器将有时间显示更改。 您可以将 requestAnimationFrame 更改为 setTimeout(processChunk, 10)。 问题是,如果您在该过程完成之前选中另一个复选框,某些行可能会处于不一致的状态,因此您必须注意这一点。
关于javascript更新大表的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22120125/