1

我有一个大表,目前由 95x120=11400 个 TD 组成,并且想动态编辑来自某个行或列,甚至是一堆行/列的所有单元格的高度和背景颜色等属性。我想这样做是为了让用户能够调整行/列的大小等。什么是完成这项工作的好方法?

顺便说一句,我表中的所有 TD 都具有唯一的行/列类,例如在通过 Javascript 构建表时动态添加的 row1、row2、row3、col1、col2、col3。

4

4 回答 4

3

这可以通过动态修改 css-rules 来非常有效地完成。在规则中存储常用属性(即一行单元格的高度)而不是将其全部存储在每个元素中也更有意义。而且它占用的内存也更少。

使用如下表格布局:

<table>
    <tr>
        <td class="row1 col1">data</td>
        <td class="row2 col2">data</td>
        <td class="row3 col3">data</td>
    </tr>
    <tr>
        <td class="row1 col1">data</td>
        <td class="row2 col2">data</td>
        <td class="row3 col3">data</td>
    </tr>
    <tr>
        <td class="row1 col1">data</td>
        <td class="row2 col2">data</td>
        <td class="row3 col3">data</td>
    </tr>
</table>

我们可以这样做:

var numRows=3, numCols=3;
document.getElementsByTagName('head')[0].appendChild(document.createElement('style'));
var sheet=document.styleSheets[1];
//Or instead of creating a new sheet we could just get the first exisiting one like this:
//var sheet=document.styleSheets[0]; 
var selector, rule, i, rowStyles=[], colStyles=[];
//Create rules dynamically
for (i=0; i<numRows; i++) {
        selector=".row"+i;
        rule="{height:20px}";
        if (sheet.insertRule)
            sheet.insertRule(selector+rule, 0);//This puts the rule at index 0
        else
            sheet.addRule(selector2, rule2, 0);//IE does things differently
        rowStyles[i]=(sheet.rules||sheet.cssRules)[0].style;//Remember you have to fetch the rules-array from the sheet and not hold on to the old rules-array, since a new one is created during each insertion. Oh, and IE does things differently again; cssRules instead of rules
}
for (i=0; i<numCols; i++) {
        selector=".col"+i;
        rule="{background-color:white}";
        if (sheet.insertRule)
            sheet.insertRule(selector+rule, 0);
        else
            sheet.addRule(selector2, rule2, 0);
        colStyles[i]=(sheet.rules||sheet.cssRules)[0].style;
}

//Now they can be changed real easy and efficiently like this:
//This line changes the height for the second row, simply by modifying their css-rule, not setting a style-height on each element
rowStyles[1].height="50px";
//It is also really easy to adjust properties of rules added from css-file, just iterate through the rules/cssRules-array checking the selectorText-property of each object until the right one is found.

我做了一些基准测试,除非我在某个地方出错,否则差异是非常巨大的。但是,是的,除了基准测试之外,它在实际用例中确实有巨大的显着差异。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>

        <style>
      td {
      border: 1px solid black;
      width: 10px;
      height: 10px;
      }
    </style>
        <script src="http://code.jquery.com/jquery-latest.min.js " charset="UTF-8"></script>
    </head>
    <body>
        <table id="table">
            <tr id="row">
            </tr>
        </table>
            <script type="text/javascript">
            var tr=document.getElementById("row");
            for (var i=0; i<300; i++) {
                var cell=tr.insertCell(0);
                cell.className="cell";
            }

            var sheet=document.styleSheets[0];
            var c2=(sheet.rules||sheet.cssRules)[0].style;
            var table=document.getElementById("table");
            var startTime;


        //First loop
        startTime=new Date().getTime();
        var c1=$(".cell");
        for (var i=0; i<1000; i++) {
            c1.height(i);
        }
        var time1=new Date().getTime()-startTime;
        //Second loop
        startTime=new Date().getTime();
        c1=$(".cell");
        for (var i=0; i<1000; i++) {
            c1.css("height",i);
        }
        time2=new Date().getTime()-startTime;
        //Third loop
        startTime=new Date().getTime();
        c1=$(".cell");
        document.body.removeChild(table);
        for (var i=0; i<1000; i++) {
            c1.css("height",i);
        }
        document.body.appendChild(table);
        time3=new Date().getTime()-startTime;
        //Fourth loop
        startTime=new Date().getTime();
        for (var i=0; i<1000; i++) {
            c2.height=i+"px";
        }
        var time4=new Date().getTime()-startTime;

        alert ("First:"+time1+" ms\nSecond:"+time2+" ms\nThird:"+time3+" ms\nForth:"+time4+" ms");
        </script>    
    </body>
</html>

由于某种原因,由此产生的结果会产生误导吗?在那种情况下,我不太清楚我哪里出错了,所以我很感激反馈。这些是我得到的结果。

完成时间:

循环 1:这个使用一个简单的 jquery 类选择器 $(".cell").height(h);

  • 铬 - 2335 毫秒
  • 歌剧 - 4151 毫秒
  • IE 9 - 3965 毫秒
  • 火狐 - 6252 毫秒
  • Safari - 2987 毫秒

循环 2:这与上面的相同,但使用 $(".cell").css("height",h) 代替。它更快

  • 铬 - 1276 毫秒
  • 歌剧 - 3183 毫秒
  • IE 9 - 2174 毫秒
  • 火狐 - 3685 毫秒
  • Safari - 2240 毫秒

循环 3:与上面相同,但它在修改之前从 DOM 中删除表,然后重新附加它。至少在 Firefox 中看起来更快

  • 铬 - 1259 毫秒
  • 歌剧 - 3079 毫秒
  • IE 9 - 2221 毫秒
  • 火狐 - 2872 毫秒
  • Safari - 2250 毫秒

循环 4:这个动态修改 css 规则:

  • 铬 - 1 毫秒
  • 歌剧 - 10 毫秒
  • IE 9 - 7 毫秒
  • 火狐 - 2 毫秒
  • Safari - 13 毫秒
于 2013-02-18T06:28:33.867 回答
1

在对如此庞大的结构进行更改时,最好先将其从文档中删除,以便在您重新插入时才重新处理它。

因此,假设您的表位于名为 的变量中table,您可以这样做:

var prnt = table.parentNode, nxtsbl = table.nextSibling;
prnt.removeChild(table);
// now do all your modifications, such as looping through rows etc.
prnt.insertBefore(table,nxtsbl);
于 2013-02-18T00:21:31.357 回答
1

您还可以执行 table.rows[0] ,它给出该行中所有 TD 的数组。然后遍历它并根据需要进行更改

于 2013-02-18T07:07:56.300 回答
0

如果您的所有单元格都标有适当的类,则非常简单。

假设您要更改某列的宽度。

$(".col3").width(newWidth);

或者,如果您想更改一堆列的宽度。

$(".col3,.col5").width(newWidth);

同样与

$(".row3,.row5,.row9,.row12").height(newHeight);

或者如果你想改变背景颜色

$(".col3").css("background-color","#ff0000");
于 2013-02-18T00:23:25.747 回答