简体   繁体   English

javascript更新大表的行

[英]javascript update the rows of a large table

I have a very large table (5000+ rows) and the user has the option to delete a cell and shifts cells below it up... 我有一个非常大的表(5000多行),用户可以选择删除一个单元格并向上移动它下面的单元格...

see this as an actual example of such table 将此视为此类表格的实际示例

The table is like 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>

and so when you check the checkbox in any of the rows, it should invoke the function add 因此,当您选中任何行中的复选框时,它应该调用函数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

        }
    }

so, once you select any checkbox, the function retrieves its parent row, and then updates the below rows. 因此,一旦选中任何复选框,该函数将检索其父行,然后更新以下行。 I have few problems, though: 不过,我有几个问题:

1- The browser waits till the end of the loop to update each following row, so it takes a long time 5-10 seconds till each action is completed. 1-浏览器一直等到循环结束才更新后面的每一行,因此完成每个动作都需要5到10秒的长时间。 I want to update the table after each iteration. 我想在每次迭代后更新表。

2- I do not want to shift the whole row down, but only the side selected (the three left or the three right . So how can I select particular TDs within the selected row and update their innerHTML according to respective TDs from the following rows (and vice versa)? 2-我不希望将整个行向下移动,而只希望将所选的一侧向下移动(左三个或三个右。因此,如何选择所选行中的特定TD,并根据随后各行中的各个TD更新其innerHTML (反之亦然)?

3- I want to eventually be able to select multiple cells and delete them, so I do not want to be stuck with updating the rows acording to the contents of the following siblings, but rather the siblings after an offset n rows... how can I do this? 3-我希望最终能够选择多个单元格并将其删除,所以我不想被困在根据以下同级项的内容更新行,而是在偏移n行之后的同级项。我可以这样做吗?

(should I split these questions into three separate questions better?) (我是否应该将这些问题更好地分为三个独立的问题?)

First of all using integers as ID is not allowed <tr id="797"> should be <tr id="tr797"> or similar. 首先,不允许使用整数作为ID, <tr id="797">应该为<tr id="tr797">或类似的值。

Your biggest issue in this example is that the DOM (the rendered html source) is very slow to iterate. 在此示例中,最大的问题是DOM(呈现的html源代码)的迭代速度非常慢。 You will never get this up in speed with the current pattern and chosen programming technique. 使用当前的模式和选择的编程技术,您将永远无法加快速度。 You should somehow, maybe meanwhile you render the DOM or before that, construct an array or JSON with your data. 您应该以某种方式,也许同时渲染DOM,或者在此之前,使用数据构造一个数组或JSON。

An example of the json would be json的示例是

var example = {
    "rows": [
        {
            "row": "tr797",
            "checkbox1": "s797",
            "checkbox2": "t797"
        },
        {
            "row": "tr798",
            "checkbox1": "s798",
            "checkbox2": "t798"
        },
    ]
}

Also, instead of the onclick="add(this);" 另外,代替onclick="add(this);" command that requires the browser to iterate the DOM at each click you should consider an event handler or help the code by doing something like onclick="add('s797');" 该命令要求浏览器在每次单击时都对DOM进行迭代,因此您应该考虑使用事件处理程序或通过执行类似onclick="add('s797');"类的操作来帮助代码onclick="add('s797');"

Combining the above you will need some methods to find in this JSON and its data structure 结合以上内容,您将需要一些方法来查找此JSON及其数据结构

function find(elementId, elementName) {
    var items = example.rows.filter(function (item) {
        return item[elementName] === elementId;
    });

    return items.length == 1 ? items[0] : null;
};

To use this implement the following pattern on your onclicks onclick="add('tr797', "row");" 要使用此工具,请在onclicks上使用以下模式onclick="add('tr797', "row");" ... onclick="add('s798', "checkbox");" ... onclick="add('s798', "checkbox");" .

Well, of course you'll need to extend the JSON with all the data you are selecting in your routine but that should be pretty easy, it'll be quite fast anyway! 好吧,当然,您需要使用例程中选择的所有数据扩展JSON,但这应该很容易,反正它会非常快!

I don't really get what you're trying to do when you check a checkbox. 当您选中一个复选框时,我真的不明白您要做什么。 It seems that you're removing the row below it, but in a strange way. 似乎您要删除它下面的行,但是用一种奇怪的方式。 Every time you check a checkbox, you delete the contents of a row in the bottom. 每次您选中一个复选框时,都会删除底部一行的内容。 Wouldn't it be easier to just remove a row, instead of updating every row in the table? 仅删除一行而不是更新表中的每一行会更容易吗?

Anyway, if what you want is to 'see' the rows updating, you will have to split your updating loop to give time to the browser to render. 无论如何,如果您要“查看”行更新,则必须拆分更新循环,以留出时间给浏览器进行渲染。 The best way to achieve this is by using requestAnimationFrame, though it isn't supported in IE9 and below. 最好的方法是使用requestAnimationFrame,尽管IE9及以下版本不支持它。 Basically, requestAnimationFrame acts similarly to setTimeout (which you can use if you need to support older browsers), but instead of executing after a period of time, it will execute next time the browser needs to render a frame (synchronously with vertical sync). 基本上,requestAnimationFrame的行为与setTimeout相似(如果需要支持较旧的浏览器,则可以使用setTimeout),但不是在一段时间后执行,而是下次浏览器需要渲染帧时执行(与垂直同步同步)。

So you should create a function like this: 因此,您应该创建如下函数:

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;
    }
}

With this code, ten rows will be updated and then the browser will have time to show the changes. 使用此代码,将更新十行,然后浏览器将有时间显示更改。 You could change requestAnimationFrame for setTimeout(processChunk, 10). 您可以将requestAnimationFrame更改为setTimeout(processChunk,10)。 the problem is that if you check another checkbox before the process completes, some rows could be in an inconsistent state, so you'll have to take care with that. 问题是,如果您在流程完成之前选中另一个复选框,则某些行可能处于不一致状态,因此您必须注意这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM