Javascript 如何以良好的方式修改大量元素的属性?

Javascript 如何以良好的方式修改大量元素的属性?,javascript,jquery,html,Javascript,Jquery,Html,我有一个很大的表格,目前由95x120=11400 TD组成,我想动态编辑某一行或某一行中所有单元格的高度和背景色等属性 列,甚至是一组行/列。我想这样做是为了让用户能够调整行/列的大小。 做这件事的好方法是什么 顺便说一句,我的表中的所有TD都为row/col添加了唯一的类,例如row1、row2、row3、col1、col2、col3,而该表是通过Javascript构建的。在对如此庞大的结构进行更改时,最好先将其从文档中删除,以便它只在最后得到重新处理,重新插入时 因此,假设您的表位于名为

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


顺便说一句,我的表中的所有TD都为row/col添加了唯一的类,例如row1、row2、row3、col1、col2、col3,而该表是通过Javascript构建的。

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

因此,假设您的表位于名为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);

在对如此庞大的结构进行更改时,最好先将其从文档中删除,这样在最后重新插入时,它才会得到重新处理

因此,假设您的表位于名为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);

如果您的所有单元格都使用适当的类进行标记,那么就非常简单了

假设要更改某列的宽度

$(".col3").width(newWidth);
或者,如果要更改一组列的宽度

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

$(".row3,.row5,.row9,.row12").height(newHeight);
或者如果你想改变背景颜色

$(".col3").css("background-color","#ff0000");

如果您的所有单元格都使用适当的类进行标记,那么就非常简单了

假设要更改某列的宽度

$(".col3").width(newWidth);
或者,如果要更改一组列的宽度

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

$(".row3,.row5,.row9,.row12").height(newHeight);
或者如果你想改变背景颜色

$(".col3").css("background-color","#ff0000");

通过动态修改css规则,可以非常有效地实现这一点。存储公共属性(即规则中一行单元格的高度)比将其全部存储在每个元素中更有意义。而且它占用的内存也更少

使用如下所示的表格布局:

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

铬-2335ms 歌剧院-4151毫秒 IE 9-3965毫秒 Firefox-6252毫秒 Safari-2987 ms 循环2:这一个与上面相同,但使用$.cell.csheight,而不是h。更快

铬-1276ms 歌剧院-3183毫秒 IE 9-2174 ms Firefox-3685毫秒 Safari-2240毫秒 循环3:与上面相同,但它在修改之前从DOM中删除表,然后重新追加它。至少在Firefox中看起来更快

铬-1259毫秒 歌剧院-3079毫秒 IE 9-2221毫秒 Firefox-2872ms Safari-2250毫秒 循环4:此循环动态修改css规则:

铬-1毫秒 歌剧院-10毫秒 IE 9-7毫秒 Firefox-2ms Safari-13毫秒
通过动态修改css规则,可以非常有效地实现这一点。存储公共属性(即规则中一行单元格的高度)比将其全部存储在每个元素中更有意义。而且它占用的内存也更少

使用如下所示的表格布局:

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

铬-2335ms 歌剧院-4151毫秒 IE 9-3965毫秒 Firefox-6252毫秒 Safari-2987 ms 循环2:这一个与上面相同,但使用$.cell.csheight,而不是h。更快

铬-1276ms 歌剧院-3183毫秒 IE 9-2174 ms Firefox-3685毫秒 Safari-2240毫秒 循环3:与上面相同,但它在修改之前从DOM中删除表,然后重新追加它。至少在Firefox中看起来更快

铬-1259毫秒 歌剧院-3079毫秒 IE 9-2221毫秒 Firefox-2872ms Safari-2250毫秒 循环4:此循环动态修改css规则:

铬-1毫秒 歌剧院-10毫秒 IE 9-7毫秒 Firefox-2ms Safari-13毫秒
您还可以执行table.rows[0],它给出了该行中所有TDs的数组。然后循环遍历它并根据需要进行更改

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

获取一组要执行操作的元素,迭代该元素列表以更新属性。没有具体的细节,我不确定你能不能有一个具体的答案
。获取要对其执行操作的一组元素,并在该元素列表中迭代更新属性。由于没有具体内容,我不确定你是否能得到具体的答案。使用标签可以更有效地完成专栏。类似地,通过使用标记而不是其中的s,可以更高效地处理行。使用标记可以更高效地处理列。类似地,通过使用标记,而不是使用其中的s,可以更有效地完成行。以编程方式更改CSS规则似乎是一条可行之路。但是,我会修改前三个示例,因为现在在进行此jQuery调用c1=$.cell;之前计时器启动似乎有点不公平;。对所有匹配的单元格进行DOM搜索似乎与精确测量在这些元素上设置CSS属性所需的时间无关。是的,事实上,我是这样写的,但后来改变了它。对于静态大小表,正如您所说,我们可以将$.cell保存到循环外的变量中,但是如果可能添加了新的单元格,我们必须这样做。所以我想这取决于=。我想即使大小是动态的,我们也可以把它放在外面,如果我们确保在大小改变时从c1中添加/删除单元格……好的,我同意大多数时候不需要DOM搜索。比如在调整行大小时。当用户调整大小时,不会添加新单元格。当我能够重新进行基准测试时,我将改变这一点。我打赌差别不会很大,因为jquery在可用时使用document.getElementsByClassName。这方面的工作非常出色。以编程方式更改CSS规则似乎是一条可行之路。但是,我会修改前三个示例,因为现在在进行此jQuery调用c1=$.cell;之前计时器启动似乎有点不公平;。对所有匹配的单元格进行DOM搜索似乎与精确测量在这些元素上设置CSS属性所需的时间无关。是的,事实上,我是这样写的,但后来改变了它。对于静态大小表,正如您所说,我们可以将$.cell保存到循环外的变量中,但是如果可能添加了新的单元格,我们必须这样做。所以我想这取决于=。我想即使大小是动态的,我们也可以把它放在外面,如果我们确保在大小改变时从c1中添加/删除单元格……好的,我同意大多数时候不需要DOM搜索。比如在调整行大小时。当用户调整大小时,不会添加新单元格。当我能够重新进行基准测试时,我将改变这一点。我打赌差别不会很大,因为jquery在可用时使用document.getElementsByClassName。