JQuery addClass和removeClass效率

发布于 2024-12-01 09:28:38 字数 1134 浏览 2 评论 0原文

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

这里有一些信息,以便您可以更好地理解我的代码在做什么。

该代码是从单击事件中执行的,并且 $(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),这对我来说还可以......只是看起来已经完成了很多工作。

有什么想法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初见你 2024-12-08 09:28:38

如果您没有为这些对象分配任何其他动态类,则可以将 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(),但它也更脆弱,并且对于您实际尝试进行的更改来说可读性较差。如果您决定向这些对象添加更多类,则必须修改此代码以适应它们。只有您可以决定这种额外的性能是否值得稍微降低可维护性。

您可以通过仅执行一个选择器操作来减少选择器操作的数量,然后使用自定义函数对其进行迭代,以确定每个对象是否在该对象下,并为其分配适当的类名。这既减少了 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 测试,其中只有 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 中得到了更加显着的差异(你的方法甚至更慢,我的快速方法甚至更快)。

因此,如果这与您的应用程序相关,那么事情似乎确实可以比您拥有的速度快得多。

If you don't have any other dynamic classes being assigned to these objects, then you can replace o.removeClass().addClass() with o.attr("className", xxx) since you know what the final result should be and you can speed it up by a factor of 3x (in my test case).

With your HTML and your code, I think it could be reduced to this:

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

This should be faster because there's half as many jQuery calls and just setting an attribute is way faster than addClass() and removeClass(), but it is also more brittle and a bit less readable for what changes you're actually trying to make. If you ever decide to add more classes to these objects, this code will have to be modified to account for them. Only you can decide if this additional performance is worth a little reduction in maintainability.

You could reduce the number of selector operations by doing just one selector operation and then iterating over it with a custom function to decide whether each object is under this or not and assign it an appropriate className. This both reduces the number of DOM searches, but also prevents duplicate assignment of className. That would look something like this:

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

Putting all three of these into a jsperf test with only 10 items in the iteration, I get this in Chrome:

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

I get an even more dramatic difference in Firefox 6 (your method is even slower, my fast method is even faster).

So, it does appear things can be made to go a lot faster than what you have if that's relevant in your app.

彩扇题诗 2024-12-08 09:28:38

我认为这并不重要,但也许这更快(而且你知道如何衡量它,所以我让你来评判):

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

但据我所知,这并不重要。

I think it won't matter much, but maybe this is faster (and you know how to measure it, so I'll let you be the judge):

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

But it won't matter that much afaik.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文