JQuery addClass和removeClass效率

时间:2011-08-24 20:05:16

标签: jquery optimization addclass removeclass

我正在构建一个可排序的表,需要更新表头上的'排序顺序'图标。

这是一些信息,因此您可以更好地了解我的代码正在做什么。

代码正在点击事件中执行,$(this)引用被点击的表格标题单元格。

表格标题单元格中有三个跨度;包装器,文本范围和图标范围。这是它的外观

<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$("thead:first th")

的回复

这是我的代码,可以切换图标。

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);

您可以看到它选择所有标题图标单元格,删除可能存在的任何图标类,然后重新添加适用的类。然后,我抓住单击的单元格图标,删除任何图标类,并应用相应的类。

这是最好的方法吗?它工作..并且它在大约7毫秒(Windows 7,FF6.0)中执行,这对我来说是好的..看起来它正在做很多工作。

有什么想法吗?

2 个答案:

答案 0 :(得分: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()removeClass()快,但它也更脆弱,对你的改变更不易读实际上是想做。如果您决定向这些对象添加更多类,则必须修改此代码以考虑它们。只有您可以决定这种额外性能是否值得稍微降低可维护性。

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

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";
    }
});

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

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

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

所以,看起来事情可以比你的应用程序中的相关内容快得多。

答案 1 :(得分: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);

但这并不重要。