我有一个非常大的表(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更新其内部HTML)以下行(反之亦然)?
3-我希望最终能够选择多个单元格并删除它们,所以我不想被困在根据以下兄弟的内容更新行,而是在偏移n行之后的兄弟姐妹。 ..我怎么能这样做?
(我应该将这些问题分成三个单独的问题吗?)
答案 0 :(得分:0)
首先,不允许使用整数作为ID,<tr id="797">
应为<tr id="tr797">
或类似。
此示例中最大的问题是DOM(呈现的html源)迭代非常慢。使用当前模式和选择的编程技术,您永远无法快速提高速度。您应该以某种方式,也许同时渲染DOM或在此之前,使用您的数据构建数组或JSON。
json的一个例子是
var example = {
"rows": [
{
"row": "tr797",
"checkbox1": "s797",
"checkbox2": "t797"
},
{
"row": "tr798",
"checkbox1": "s798",
"checkbox2": "t798"
},
]
}
此外,代替要求浏览器在每次点击时迭代DOM的onclick="add(this);"
命令,您应该考虑事件处理程序或通过执行类似onclick="add('s797');"
结合上述内容,您需要一些方法来查找此JSON及其数据结构
function find(elementId, elementName) {
var items = example.rows.filter(function (item) {
return item[elementName] === elementId;
});
return items.length == 1 ? items[0] : null;
};
要使用此功能,请在onclicks onclick="add('tr797', "row");"
上设置以下模式... onclick="add('s798', "checkbox");"
。
嗯,当然你需要使用你在日常工作中选择的所有数据扩展JSON,但这应该很简单,反正它会非常快!
答案 1 :(得分:0)
当你选中一个复选框时,我真的没有得到你想要做的事情。看起来你正在删除它下面的行,但是以一种奇怪的方式。每次选中复选框时,都会删除底部行的内容。是不是更容易删除一行,而不是更新表中的每一行?
无论如何,如果您想要“看到”行更新,则必须拆分更新循环以便为浏览器提供渲染时间。实现此目的的最佳方法是使用requestAnimationFrame,但IE9及更低版本不支持。 基本上,requestAnimationFrame的作用类似于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;
}
}
使用此代码,将更新十行,然后浏览器将有时间显示更改。 您可以为setTimeout更改requestAnimationFrame(processChunk,10)。 问题是,如果在进程完成之前检查另一个复选框,则某些行可能处于不一致状态,因此您必须小心处理。