【问题标题】:Optimizing Jquery iteration through table columns comparing with existing row通过与现有行比较的表列优化 Jquery 迭代
【发布时间】:2010-11-26 20:17:26
【问题描述】:

我正在尝试编写一个函数,以根据作为表格顶部行之一的引用为表格添加颜色。 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 扩展/插件,大表不会对 Google Chrome 浏览器造成威胁,加载需要几秒钟,但是 Opera、Firefox 和 Internet Explorer 很难运行该功能或最终要求用户交互停止脚本运行。

所以我的问题是针对column select plugin 的替代方案或优化代码的方法,以便我不会杀死除 Google Chrome 之外的几乎所有浏览器。

编辑:根据@Pointy的两个cmets进行更改

【问题讨论】:

  • 别忘了在for 循环中用var 声明“i”!!!!
  • 另外,像这样设置“类”并不是一个好主意——使用addClass()removeClass()
  • @Pointy .attr() 使用旨在替换所有可归因于元素的类。这不是一个“坏主意”,因为它是 JQuery 文档中推荐的方法。
  • 如果我们变得挑剔,请使用 .length 而不是 .size!
  • @Unode 好吧,如果那是你真正想要的。你也可以在 DOM 上设置原始的“className”属性。就我个人而言,我希望有类似.toggleClass() 的东西让我为true 案例提供一个类,为false 提供一个不同的类...

标签: javascript jquery optimization jquery-plugins


【解决方案1】:

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

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

【讨论】:

  • 我只想添加一条评论,说明使用什么以及为什么使用elem.textContent || elem.innerText,您的回答是完美的。竖起大拇指!
  • 为什么不在 refcells 上也使用 DOM 元素呢?性能略有提高,但仍然更快 - jsperf.com/color-column/3
  • 我更新了DOM文本部分,基本上是modern browsers || IE &lt;= 8。是的,它可以在参考单元上使用,但它们的数量是有限的,所以它的收益很小。然而,真正的单元格与行号相关,因此它们更为重要。我很高兴能帮上忙。
【解决方案2】:

做你正在做的事情将是非常计算密集型的。由于您的表格布局看起来很规则,我将完全放弃 nthCol() 的东西(无论如何对于此页面)并通过迭代表格一次来完成您的工作:

  1. 先抓取“key”行,然后保存
  2. 循环遍历每个相关的&lt;tr&gt;,并为每一个获取&lt;td&gt; 元素,并将它们作为原始节点列表或作为jQuery 列表进行迭代。无论哪种方式,它都应该快得多。
  3. 在第二个循环中,您将执行与您相同的逻辑(尽管我会使用 addClass()removeClass()),返回每个单元格的已保存“键”行。

在您当前的循环中,您正在为每一列在表中重新构建 every &lt;td&gt; 的 jQuery 对象,并且 然后 您正在这样做nthCol() 工作!如果您执行一次,则需要做很多工作,因此对每一列重复此操作会真正拖累 CPU。 (在 IE6 上——尤其是所有这些“类”变化——我敢打赌,它的速度几乎无法忍受。)

edit — 我查看了该代码(针对插件),虽然它看起来被很好地实现了,但它没有任何“魔术技巧”。它所做的只是遍历您提供给它的所有表格单元格,并检查每个单元格实际上是否在“第 n”列中。因此,您的迭代将对您关心的每一列的表中的每个单元格执行该测试。在您的 90x20 表中,这将是通过所有 1800 个单元格进行大约 85 次迭代。那是你做你的工作之前!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 2021-10-20
    • 2020-12-03
    • 2016-11-22
    • 1970-01-01
    • 2021-10-22
    相关资源
    最近更新 更多