2

I am building a sortable table and need the update the 'sort order' icons on the table header.

Here is a little information so you can better understand what my code is doing.

The code is being executed from within a click event, and $(this) references the table header cell being clicked.

The table header cell has three spans in it; a wrapper, a text span, and a icon span. Here is how it looks

<span class='ui-button ui-widget ui-state-default ui-button-text-icon-secondary'>
  <span class='ui-button-text'>text</span>
  <span class='ui-button-icon-secondary ui-icon ui-icon-triangle-2-n-s'></span>
</span>

collection is a return from $("thead:first th")

and here is my code that does the switch on the icons.

var new_class = sort_info.order == "asc" ? "ui-icon-triangle-1-n" : "ui-icon-triangle-1-s";
collection.find(".ui-icon").removeClass("ui-icon-triangle-1-n ui-icon-triangle-1-s ui-icon-triangle-2-n-s").addClass("ui-icon-triangle-2-n-s");
$(this).find(".ui-icon").removeClass("ui-icon-triangle-1-n ui-icon-triangle-1-s ui-icon-triangle-2-n-s").addClass(new_class);

as you can see it selects all header icon cells, removes any icon classes that may exist, then re-adds the applicable class. THEN i grab the clicked cells' icon, remove any icon classes, and apply the appropriate class.

Is this the best way to do this? It works.. and it executes in roughly 7 ms (Windows 7, FF6.0) which is ok by me.. just looks like it's a lot of work being done.

any thoughts?

4

2 回答 2

4

如果您没有为这些对象分配任何其他动态类,那么您可以替换o.removeClass().addClass()为,o.attr("className", xxx)因为您知道最终结果应该是什么,并且可以将其加速 3 倍(在我的测试用例中)。

使用您的 HTML 和代码,我认为可以简化为:

var new_class = sort_info.order == "asc" ? "ui-icon-triangle-1-n" : "ui-icon-triangle-1-s";
collection.find(".ui-icon").attr("className", "ui-button-icon-secondary ui-icon ui-icon-triangle-2-n-s"); 
$(this).find(".ui-icon").attr("className", "ui-button-icon-secondary ui-icon " + new_class);

这应该更快,因为有一半的 jQuery 调用,并且仅设置属性比addClass()and快得多removeClass(),但是对于您实际尝试进行的更改,它也更脆弱且可读性更低。如果您决定向这些对象添加更多类,则必须修改此代码以考虑它们。只有您可以决定这种额外的性能是否值得稍微降低可维护性。

您可以减少选择器操作的数量,方法是只执行一个选择器操作,然后使用自定义函数对其进行迭代,以确定每个对象是否在此之下,并为其分配适当的类名。这既减少了 DOM 搜索的次数,又防止了类名的重复分配。看起来像这样:

var new_class = sort_info.order == "asc" ? "ui-icon-triangle-1-n" : "ui-icon-triangle-1-s";
var that = this;
collection.find(".ui-icon").each(function() {
    if ($.contains(that, this)) {
        this.className = "ui-button-icon-secondary ui-icon " + new_class;
    } else {
        this.className = "ui-button-icon-secondary ui-icon ui-icon-triangle-2-n-s";
    }
});

将所有这三个都放入迭代中只有 10 个项目的jsperf 测试中,我在 Chrome 中得到了这个:

Your method: 6691 ops/sec
Direct set of className: 11,210 ops/sec
Iteration with single selector: 20,280 ops/sec

我在 Firefox 6 中得到了更显着的差异(你的方法更慢,我的快速方法更快)。

因此,如果这与您的应用程序相关,似乎可以使事情变得比您拥有的要快得多。

于 2011-08-24T20:53:43.423 回答
1

我认为这无关紧要,但也许这更快(你知道如何衡量它,所以我会让你来评判):

var new_class = sort_info.order == "asc" ? "ui-icon-triangle-1-n" : "ui-icon-triangle-1-s";
collection.not(this).find(".ui-icon-triangle-1-n, .ui-icon-triangle-1-s").removeClass("ui-icon-triangle-1-n ui-icon-triangle-1-s").addClass("ui-icon-triangle-2-n-s");
$(this).find(".ui-icon").removeClass("ui-icon-triangle-1-n ui-icon-triangle-1-s ui-icon-triangle-2-n-s").addClass(new_class);

但这并不重要。

于 2011-08-24T20:24:50.380 回答