2

受Learning 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)and $(b)

问:有没有办法可以缓存$(a)$(b)?作者使用了他称之为expando的东西。

这种附加到 DOM 元素但不是普通 DOM 属性的属性称为 expando。这是存储键的方便位置,因为我们需要每个表行元素一个。现在,我们可以在比较器函数中检查这个属性,我们的排序明显更快。

4

3 回答 3

3

您可以在此处进行两项优化。

首先是使用$.data而不是$.fn.data

$.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;
});

第三个优化(因为一个孤独的答案是买二送一)是使用 jQuery 1.7,它在速度和其他功能上都比 1.3 好得多。

于 2012-04-07T17:02:12.547 回答
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;
});​
于 2012-04-07T16:58:53.530 回答
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 对象的这个属性:您可以随时在它们上创建新属性。

于 2012-04-07T17:01:58.377 回答