受到学习jQuery 1.3第7章的启发(第三版中没有),我把这个例程放在一起:
var rows = $table.find('tbody > tr').get();
$.each(rows, function(index, row) {
var $cell = $(row).children('td').eq(column);
$(row).data('sortKey',$cell);
});
rows.sort(function(a, b) {
if ($(a).data('sortKey') < $(b).data('sortKey'))
return -sortDirection;
if ($(a).data('sortKey') > $(b).data('sortKey'))
return sortDirection;
return 0;
});
但我不喜欢在每一行使用$(a)
和$(b)
。
问:有没有办法可以缓存$(a)
和$(b)
?作者使用了他称之为 expando 的东西。
这种属性,附加到DOM元素但不是普通的DOM 属性,称为expando。这是一个方便存放的地方 关键,因为每个表行元素需要一个。现在,我们可以检查一下 比较器函数中的这个属性,我们的排序是 明显更快。
答案 0 :(得分:3)
你可以在这里做两个优化。
$.data(a, 'sortKey') // quick
$(a).data('sortKey') // slow
这是优越的,因为它不需要构建一个新的jQuery对象 - 你认为这是一个性能问题是正确的。
第二种是缓存data
的结果,所以你只需要做一次。
rows.sort(function(a, b) {
var aKey = $.data(a, 'sortKey'),
bKey = $.data(b, 'sortKey');
if (aKey < bKey) return -sortDirection;
if (aKey > bKey) return sortDirection;
return 0;
});
第三个优化(因为lonesomeday答案是买二送一)是使用jQuery 1.7,它在速度和其他功能方面都优于1.3。
答案 1 :(得分:1)
当然,只需将它们存储在这样的局部变量中:
rows.sort(function(a, b) {
var aKey = $(a).data('sortKey');
var bKey = $(b).data('sortKey');
if (aKey < bKey) return -sortDirection;
if (aKey > bKey) return sortDirection;
return 0;
});
答案 2 :(得分:1)
作者解释说,您需要为某处的每一行存储排序键,但是 不能使用jQuery的.data
工具来存储它。而不是这样,他选择在DOM元素上创建一个新属性:
$.each(rows, function(index, row) {
var $cell = $(row).children('td').eq(column);
row.sortKey = $cell; // creates a new property!
});
当然上面的代码假定不存在名为sortKey
的现有属性(覆盖它,无论它是什么,都可能导致各种问题)。这是一个合理的假设。
之后,您还必须通过用于存储它的相同机制检索排序键:通过访问要比较的两行上的属性:
rows.sort(function(a, b) {
if (a.sortKey < b.sortKey)
return -sortDirection;
if (a.sortKey > b.sortKey)
return sortDirection;
return 0;
});
由于直接属性访问比通过jQuery的.data
以及用于实现它的代码快得多,因此可以大幅提高速度。唯一的缺点是你失去了jQuery的抽象数据存储的便利性(保证“只是工作”,你不需要打扰它是如何工作的),因为你现在已经承担了实施的责任数据存储(这里,通过在DOM元素上创建一个新属性)。
作为一个注释,作者使用术语“expando”来准确描述所有JavaScript对象的这个属性:您可以随时在它们上创建新属性。