通过与现有行比较的表列优化Jquery迭代

时间:2010-11-25 21:29:42

标签: javascript jquery optimization jquery-plugins

我正在尝试编写一个函数,根据引用添加颜色到表中,该引用是表的顶行之一。在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 column cell select plugin来执行上述任务。

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");
            }
        });
    }
});

可以看到一个工作示例here。在该示例中,该表只有9行和10个数据列。我正在尝试优化的实际页面有20行和90个数据列。

使用上面提到的Javascript扩展/插件,大尺寸的桌面不会对谷歌Chrome浏览器构成威胁,只需加载几秒钟,但Opera,Firefox和Internet Explorer很难运行该功能或最终要求用户交互停止脚本运行。

所以我的问题是针对column select plugin的两种替代方法或优化代码的方法,这样我几乎不会杀死除谷歌浏览器之外的所有浏览器。

修改:根据@Pointy的两条评论进行更改

2 个答案:

答案 0 :(得分:2)

如果需要,您可以轻松获取 10x faster 代码。只需保存一次引用,然后逐行而不是逐列。它不会变得更复杂,但它的表现要好得多。原因是您的插件隐藏了抽象,表示您的表由列组成的行组成。而不是相反。模仿第二个版本可以是 costy ,正如您在此示例中所注意到的那样。

您也可以使用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";
    }
  }
});

答案 1 :(得分:0)

做你正在做的事情将是非常计算密集型。由于你的表格布局似乎非常规则,我只是完全抛弃了nthCol()事物(无论如何都是这个页面)并通过迭代表格一次来完成你的工作:

  1. 首先抓住“关键”行并保存
  2. 循环遍历每个相关的<tr>,并为每个元素获取<td>元素,并将它们作为原始节点列表或jQuery列表进行迭代。无论哪种方式它都应该快得多。
  3. 在第二个循环中,您将使用相同的逻辑(尽管我使用addClass()removeClass()),并返回每个单元格保存的“key”行
  4. 在当前循环中,您将为每列重新构建表中每个 <td>的jQuery对象,然后您就是做nthCol()工作!如果你这样做一次,那要做很多工作,所以对每一列重复这样做会真正拖累那个CPU。 (在IE6上 - 特别是对所有那些“类”的改变 - 我敢打赌这几乎是无法忍受的慢。)

    编辑 - 我查看了该代码(对于插件),虽然它看起来很有效,但它没有任何“魔术”。它所做的只是迭代你给它的所有表格单元格,并检查每个单元格是否实际上在“第n”列中。因此,对于您关心的每一列,您的迭代将对表中的每个单元格执行该测试。在你的90x20表格中,所有1800个单元格的重复次数约为85次。那是之前你做的工作!