3

我在一个页面上有一堆复选框,我一次只显示这些复选框的一个子集。

然后我执行一些操作,循环遍历所有复选框并查看它们是否被选中:

例如

$(".delete_items").click( function() {
     $('.checkboxes' ).each(function(){
     //do stuff
     }
}

然后我在想,既然用户永远不能与隐藏的复选框交互,那么将 :visible 添加到复选框会加快循环

例如

$(".delete_items").click( function() {
     $('.checkboxes :visible' ).each(function(){
     //do stuff
     }
}

但我不知道添加 :visible 是否会增加更多开销。有什么想法吗?

4

3 回答 3

9

:visible肯定会增加更多开销,因为 jQuery 必须检查几个属性是否可见元素:

元素可以被认为是隐藏的,原因如下:

  • 它们的 CSS 显示值为 none。
  • 它们是 type="hidden" 的表单元素。
  • 它们的宽度和高度明确设置为 0。
  • 祖先元素是隐藏的,因此该元素不会显示在页面上。

来源 — :hidden Selector | jQuery API 文档

特别是最后一点似乎意味着为每个增加开销的元素遍历 DOM。

如果只使用类作为选择器,jQuery 可以使用浏览器函数,如getElementsByClassquerySelectorAll

另一方面,如果您对这些复选框执行计算复杂的操作,则循环访问较少的复选框可能会超过之前的查找。

您肯定必须自己进行基准测试。

更新:

将另一个类分配给可见复选框并选择它们的另一个想法

$('.checkboxes.otherClass')

那绝对应该比使用:visible.

更新 2:

我创建了一个 jsPerf:http: //jsperf.com/jquery-visible-test

它可能不是最好的测试用例,但至少对我来说(Chrome 8、Mac OS X 10.6),使用:visible速度要慢约 45%(在 Firefox 3.6.13 中更糟:慢约 75%)。

更新 3:

使用两个类似乎更快,我更新了测试用例。

于 2011-01-14T22:50:02.920 回答
1

好吧,你会想添加

$('.checkboxes:visible') 

(注意缺少空格)因为您只关心可见复选框,而不关心任何作为复选框后代的可见项目。一旦你解决了这个问题,那么,不......添加一个可见的选择器不应该增加任何明显的开销。

话虽如此,我认为,除非您的页面上有很多复选框,否则您就是在进行微优化。除非您真的注意到性能下降,否则不要担心可见或不可见(我认为此时最好保持状态一致和可预测)并让您的代码正常工作。

于 2011-01-14T22:50:36.227 回答
1

我不太确定隐形复选框是否重要。如果您不介意包括它们,只需使用类选择器querySelectorAll,然后按照 Felix King 的建议来完成繁重的工作。

另一方面,如果您确实介意只在可见复选框上工作,则可以在选中它们时确定它们的可见性。这将明显更快,因为您不需要检查未检查的可见性元素。您也可以作弊并使用内部 jQuery 函数jQuery.expr.filters.visible,这是一种更快的调用方式$(this).is(':visible')

$('.checkboxes' ).each(function(){
    if (this.checked && jQuery.expr.filters.visible(this)) {
        // checkbox is visible and checked
    }
}

请注意,虽然这在 jQuery 1.4.4 中有效,但它没有记录在案并且可能随时更改......

正如其他用户所提到的,除非您遇到严重的性能问题,否则不要过度优化。如果您愿意,此解决方案可能有用。

编辑一些基准测试表明,如果您的要求是仅在选中的可见复选框上工作,我的解决方案大约是 的两倍$('.checkboxes:visible'),假设您没有应用相关的类。

于 2011-01-14T23:03:51.503 回答