How do you modify properties of a large amount of

2020-06-07 04:39发布

I have a large table currently consisting of 95x120=11400 TD's and would like to dynamically edit properties such as height and background-color for all the cells from a certain row or column, or even a bunch of rows/columns. I want to do this in order to make the user able to resize rows/columns among other things. What would be a good way of getting that done?

All the TD's in my table does by the way have unique class for row/col eg row1, row2, row3, col1, col2, col3 added dynamically while the table is built up though Javascript.

4条回答
我想做一个坏孩纸
2楼-- · 2020-06-07 05:09

You can also do table.rows[0] which gives a array of all TDs in that row. Then loop through it and change as wanted

查看更多
女痞
3楼-- · 2020-06-07 05:09

Pretty simple if all of your cells are labeled with the appropriate classes.

Say you want to change the width of a certain column.

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

Or if you want to change the width of a bunch of columns.

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

Similarly with

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

Or if you want to change the background color

$(".col3").css("background-color","#ff0000");
查看更多
闹够了就滚
4楼-- · 2020-06-07 05:18

When making changes to such a huge structure, it is a good idea to remove it from the document first, so that it only gets re-processed at the end, when you re-insert it.

So, assuming your table is in a variable named table, you would do this:

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);
查看更多
够拽才男人
5楼-- · 2020-06-07 05:29

This can be done really efficiently by modifying css-rules dynamically. It also makes a lot more sense storing common properties i.e. height for a row of cells in a rule rather than storing it all in each element. And it takes up less memory as well.

With a table-layout like the following:

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

We can do something like this:

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.

I did a bit of benchmarking and unless I'm going wrong somewhere the difference is quite tremendous. But yeah, apart from the benchmark it really does a huge noticeable difference in the real use case.

<!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>

Would results from this be misleading for some reason? In that case I can't quite see where I'm going wrong so I'd appreciate feedback. These are the results I get.

Time taken to complete:

Loop 1: This one uses a simple jquery class-selector $(".cell").height(h);

  • Chrome - 2335 ms
  • Opera - 4151 ms
  • IE 9 - 3965 ms
  • Firefox - 6252 ms
  • Safari - 2987 ms

Loop 2: This one is same as above but uses $(".cell").css("height",h) instead. It's faster

  • Chrome - 1276 ms
  • Opera - 3183 ms
  • IE 9 - 2174 ms
  • Firefox - 3685 ms
  • Safari - 2240 ms

Loop 3: Same as above but it removes the table from DOM before modifying, then re-appending it. Seems faster in Firefox at least

  • Chrome - 1259 ms
  • Opera - 3079 ms
  • IE 9 - 2221 ms
  • Firefox - 2872 ms
  • Safari - 2250 ms

Loop 4: This one modifies the css-rules dynamically:

  • Chrome - 1 ms
  • Opera - 10 ms
  • IE 9 - 7 ms
  • Firefox - 2 ms
  • Safari - 13 ms
查看更多
登录 后发表回答