我正在尝试编写一个函数,根据引用添加颜色到表中,该引用是表的顶行之一。在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的两条评论进行更改
答案 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()
事物(无论如何都是这个页面)并通过迭代表格一次来完成你的工作:
<tr>
,并为每个元素获取<td>
元素,并将它们作为原始节点列表或jQuery列表进行迭代。无论哪种方式它都应该快得多。addClass()
和removeClass()
),并返回每个单元格保存的“key”行在当前循环中,您将为每列重新构建表中每个 <td>
的jQuery对象,然后您就是做nthCol()
工作!如果你这样做一次,那要做很多工作,所以对每一列重复这样做会真正拖累那个CPU。 (在IE6上 - 特别是对所有那些“类”的改变 - 我敢打赌这几乎是无法忍受的慢。)
编辑 - 我查看了该代码(对于插件),虽然它看起来很有效,但它没有任何“魔术”。它所做的只是迭代你给它的所有表格单元格,并检查每个单元格是否实际上在“第n”列中。因此,对于您关心的每一列,您的迭代将对表中的每个单元格执行该测试。在你的90x20表格中,所有1800个单元格的重复次数约为85次。那是之前你做的工作!