Оптимизация итерации Jquery по столбцам таблицы по сравнению с существующей строкой - PullRequest
2 голосов
/ 26 ноября 2010

Я пытаюсь написать функцию для добавления цвета в таблицу на основе ссылки, которая является одной из верхних строк таблицы. В SO есть несколько вопросов, касающихся упоминания итераций на основе строк, но не столько о столбцах.

Структура таблицы примерно такая:

<table id="data">
    <tr>
        <th rowspan="2">Name</th>
        <th rowspan="2">Selection</th>
        <th rowspan="2">Title</th>
        <th rowspan="2">Info1</th>
        <th rowspan="2">Info2</th>
        <th colspan="10">Data</th>
    </tr>
    <tr>
        <th>001</th>
        <th>002</th>
        <th>003</th>
        <th>004</th>
        <th>005</th>
        <th>006</th>
        <th>007</th>
        <th>008</th>
        <th>009</th>
        <th>010</th>
    </tr>
    <tr id="ref_control">
        <td></td>
        <td>RefName</td>
        <td></td>
        <td></td>
        <td></td>
        <td>A</td>
        <td>B</td>
        <td>J</td>
        <td>L</td>
        <td>Z</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
    </tr>
    <tr>
        <td><input type="checkbox" name="checkbox"/></td>
        <td>Entity 1</td>
        <td>Info...</td>
        <td>More info...</td>
        <td>Even more...</td>
        <td>A</td>
        <td>T</td>
        <td>M</td>
        <td>L</td>
        <td>Z</td>
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>2</td>
        <td>5</td>
    </tr>
    (...)
</table>

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

Код Javascript выглядит так:

$(document).ready(function() {
    // Colorize table based on matches
    // Number of Data entries - Count on the reference (2nd row)
    // and only 5th column onwards (index starts at 0)
    var datasize = $("#data tr:eq(2) td:gt(4)").length;

    // Start with column 6 (index starts at 1)
    var begin = 6;

    for (var i = begin; i < begin + datasize; ++i) {
        var curCol = $("#data td").nthCol(i);
        var ref = curCol.eq(0).text();
        curCol.not(curCol.eq(0)).each(function() {
            var data = $(this);
            if (data.text() == '') {
                data.addClass("black");
            } else if (data.text() != ref) {
                data.addClass("color");
            }
        });
    }
});

Рабочий пример можно визуализировать здесь . В примере таблица содержит только 9 строк и 10 столбцов данных. Фактическая страница, которую я пытаюсь оптимизировать, содержит 20 строк и 90 столбцов данных.

Использование упомянутых расширений / плагинов Javascript для таблицы большого размера не представляет угрозы для браузера Google Chrome, для загрузки которого требуется несколько секунд, однако Opera, Firefox и Internet Explorer испытывают трудности с запуском функции или в конечном итоге запрашивают взаимодействие с пользователем чтобы остановить выполнение скрипта.

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

Редактировать : Изменения в соответствии с двумя комментариями @ Pointy

Ответы [ 2 ]

2 голосов
/ 26 ноября 2010

Вы можете легко получить в 10 раз быстрее код, если хотите.Просто сохраните ссылки один раз и переходите строка за строкой, а не столбец за столбцом.Это не становится сложнее, но работает намного лучше.Причина в том, что ваш плагин скрывает абстракцию , что ваша таблица состоит из строк, которые состоят из столбцов.И не наоборот.Эмуляция второй версии может быть дорогостоящей , как вы заметили в этом примере.

Вы также можете использовать свойства DOM вместо методов jQuery.Они действительно просты.

// get text (modern browsers || IE <= 8)
var text = elem.textContent || elem.innerText;
// set class
elem.className = "black";

Ваш окончательный код будет выглядеть примерно так:

var refcells = $("#data tr:eq(2) td:gt(4)");
var datasize = refcells.length;
// Start with column 5
var begin = 5;
var refs = [];
var i = begin;
refcells.each(function () {
  refs[i++] = $(this).text();
});

$("#data tr:gt(2)").each(function () {
  var cells = $("td", this);
  for (var i = begin; i < begin + datasize; i++) {
    var elem = cells[i];
    var text = elem.textContent || elem.innerText;
    if (!text) {
      elem.className = "black";
    } else if (text != refs[i]) {
      elem.className = "color";
    }
  }
});
0 голосов
/ 26 ноября 2010

Выполнение того, что вы делаете, будет очень вычислительно интенсивным. Поскольку ваш макет таблицы кажется довольно регулярным, я бы просто полностью отбросил эту вещь nthCol() (для этой страницы в любом случае) и выполнил бы вашу работу, перебирая таблицу один раз :

  1. Сначала возьмите строку "ключ" и сохраните ее
  2. Переберите все соответствующие <tr>, и для каждого получите элементы <td> и выполните их итерацию в виде необработанного списка узлов или в виде списка jQuery. В любом случае это должно быть намного быстрее.
  3. Во втором цикле вы будете использовать ту же логику, что и у вас (хотя я бы использовал addClass() и removeClass()), возвращаясь к сохраненной строке «ключа» для каждой ячейки.

В вашем текущем цикле вы воссоздаете объект jQuery каждые <td> в таблице для каждого столбца, и затем вы делаете это nthCol() Работа! Это большая работа, если вы сделаете это один раз , повторяя, что для каждого отдельного столбца будет реально затягивать этот ЦП. (На IE6 - особенно со всеми этими «классовыми» изменениями - держу пари, это почти невыносимо медленно.)

изменить & mdash; Я просмотрел этот код (для плагина), и, хотя он выглядит так, как будто он был реализован грамотно, у него нет никаких «фокусов». Все, что он делает, это перебирает все ячейки таблицы, которые вы ему даете, и проверяет, действительно ли каждая ячейка находится в «n-ом» столбце. Таким образом, ваша итерация будет выполнять этот тест для каждой ячейки таблицы для каждого столбца, который вас интересует. В вашей таблице 90x20 это будет около 85 итераций по всем 1800 ячейкам. И это до вы делаете свою работу!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...