1

現在95x120=11400 TDで構成されている大きなテーブルがあり、特定の行または列、あるいは一連の行/列のすべてのセルの高さや背景色などのプロパティを動的に編集したいと考えています。ユーザーが特に行/列のサイズを変更できるようにするために、これを実行したいと思います。それを成し遂げる良い方法は何でしょうか?

ちなみに、私のテーブルのすべてのTDには、行/列の一意のクラスがあります。たとえば、行1、行2、行3、列1、列2、列3は、テーブルがJavascriptを介して構築されている間に動的に追加されます。

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);を使用します。

  • Chrome-2335ミリ秒
  • Opera-4151ミリ秒
  • IE9-3965ミリ秒
  • Firefox-6252ミリ秒
  • サファリ-2987ミリ秒

ループ2:これは上記と同じですが、代わりに$( "。cell")。css( "height"、h)を使用します。より速い

  • Chrome-1276ミリ秒
  • Opera-3183ミリ秒
  • IE9-2174ミリ秒
  • Firefox-3685ミリ秒
  • Safari-2240ミリ秒

ループ3:上記と同じですが、変更する前にDOMからテーブルを削除してから、再度追加します。少なくともFirefoxでは速いようです

  • Chrome-1259ミリ秒
  • Opera-3079ミリ秒
  • IE9-2221ミリ秒
  • Firefox-2872ミリ秒
  • サファリ-2250ミリ秒

ループ4:これはcss-rulesを動的に変更します:

  • Chrome-1ミリ秒
  • Opera-10ミリ秒
  • IE9-7ミリ秒
  • Firefox-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

また、その行のすべてのTDの配列を提供するtable.rows[0]を実行することもできます。次に、それをループして、必要に応じて変更します

于 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 に答える