Как вы хорошо изменяете свойства большого количества элементов?

У меня есть большая таблица, в настоящее время состоящая из 95x120 = 11400 TD и желающая динамически редактировать такие свойства, как высота и фоновый цвет для всех ячеек из определенной строки или столбец или даже ряд строк/столбцов. Я хочу сделать это, чтобы пользователь мог изменять размеры строк/столбцов между прочим. Что было бы хорошим способом добиться этого?

Все TD в моей таблице, кстати, имеют уникальный класс для строк/столбцов, например row1, row2, row3, col1, col2, col3, добавленных динамически, в то время как таблица создана, хотя Javascript.

Ответ 1

Это можно сделать очень эффективно, изменяя 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>

Из-за этого из-за этого будет вводить в заблуждение? В этом случае я не могу понять, где я ошибаюсь, поэтому буду благодарен за отзывы. Это результаты, которые я получаю.

Время выполнения:

Loop 1: Этот использует простой класс jquery-селектор $( ". cell" ). height (h);

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

Loop 2: Это то же самое, что и выше, но использует $( ". cell" ). css ( "height", h). Это быстрее

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

Loop 3: То же, что и выше, но удаляет таблицу из DOM перед изменением, а затем повторно добавляет ее. Похоже, быстрее в Firefox

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

Loop 4: Этот параметр динамически изменяет css-правила:

  • Chrome - 1 мс
  • Opera - 10 мс
  • IE 9 - 7 мс
  • Firefox - 2 мс
  • Safari - 13 мс

Ответ 2

При внесении изменений в такую ​​огромную структуру рекомендуется сначала удалить его из документа, чтобы он только повторно обрабатывался в конце, когда вы его вставляете повторно.

Итак, если ваша таблица находится в переменной с именем 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);

Ответ 3

Вы также можете сделать table.rows [0], который дает массив всех TD в этой строке. Затем прокрутите его и измените по желанию

Ответ 4

Довольно просто, если все ваши ячейки помечены соответствующими классами.

Предположим, вы хотите изменить ширину определенного столбца.

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

Или, если вы хотите изменить ширину столбца столбцов.

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

Аналогично

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

Или, если вы хотите изменить цвет фона

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