优化 Chrome 的 jquery 选择器
我有以下 jquery 代码来循环 525 个(我知道,很多!)复选框:
var elements = $("#profile-list table tr input[type=checkbox].email-checkout:not(:checked)");
$.each(elements, function(i) {
$(elements[i]).attr('checked', 'checked');
});
UPDATE html 看起来像这样:
<table>
<tr>
<th>Name</th>
<th>Title</th>
<th>E-mail</th>
<th>Telephone</th>
<th id="email_check"><img src="check_black.png"/></th>
</tr>
<?php foreach ($this->profiles as $profile): ?>
<tr>
<?php echo $this->presentProfile($profile, 'list') ?>
</tr>
<?php endforeach; ?>
这基本上会循环数据库中的所有配置文件,并为每个配置文件创建一个表行,其中最后一个表数据包含一个复选框,可以选择将电子邮件发送到该复选框。如果用户点击 id 为“email_check”的表头,那么 javascript 代码就会启动,这就是 Chrome 失败的地方。
我使用以下代码附加该事件:
$("#email_check img").live('click', function() {
//my code
}
当我在 Firefox (mac) 中运行此代码时,它会顺利进行,但是当我在 Chrome (mac) 中运行它时,它会花费很长时间,最终给我一个窗口,其中 chrome 为我提供了以下选项:杀死窗口,所以基本上它永远不会完成这个循环。
我一直在尝试尽可能地优化这个选择器,从 jquery 1.3 开始,我知道它们从左到右切换到从右到左选择器,这基本上意味着我应该尝试使最右边的选择器变得具体尽我所能。它可以比我目前的更具体吗?
或者只是需要这么长时间的循环?我尝试从 $.each 切换到常规的 for() ,但没有得到积极的结果。
有什么建议或想法可以解决这个问题吗?
英吉贝尔
I have the following jquery code to loop over 525 (I know, alot!) checkboxes:
var elements = $("#profile-list table tr input[type=checkbox].email-checkout:not(:checked)");
$.each(elements, function(i) {
$(elements[i]).attr('checked', 'checked');
});
UPDATE The html looks like this:
<table>
<tr>
<th>Name</th>
<th>Title</th>
<th>E-mail</th>
<th>Telephone</th>
<th id="email_check"><img src="check_black.png"/></th>
</tr>
<?php foreach ($this->profiles as $profile): ?>
<tr>
<?php echo $this->presentProfile($profile, 'list') ?>
</tr>
<?php endforeach; ?>
This basically loops over all profiles in the database and creates a table row for each profile, where the last table data includes a checkbox, which one can select to send email to. If the user clicks the table header with the id of "email_check" then the javascript code should kick in, and that's where Chrome fails.
I attach the event with the following code:
$("#email_check img").live('click', function() {
//my code
}
When I run this code in Firefox (mac), it goes smoothly but when I run it in Chrome (mac) it takes forever and ends up giving me the window where chrome offers me the option of killing the window, so basically it never completes this loop.
I've been trying to optimize this selector as much as I can, and since jquery 1.3, I understand that they switched from left to right to right to left selector, which basically means that I should try to make my right most selector as specific as I can. Can it be any more specific than I currently have?
Or is it the loop that just takes so long? I have tried switching from $.each to just a regular for() without a positive result.
Any tips or ideas how I can fix this?
Ingiber
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我真的认为这根本不是选择器问题。
您的选择器是
querySelectorAll
的有效选择器,这意味着它将非常快。我在 Mac 上的 Chrome 中针对 250 行的表格测试了精确选择器,结果是即时的。
我猜还有其他事情发生。
I really don't think this is a selector issue at all.
Your selector is a valid selector for
querySelectorAll
, which means it will be extremely fast.I tested the exact selector in Chrome on Mac against a table with 250 rows, and the result was instantaneous.
I'd guess that there's something else going on.
尝试删除选择器的
table tr
部分。它没有添加任何东西。Try removing the
table tr
part of the selector. It isn't adding anything.试试这个:(
所以,首先我们选择所有属于“email-checkout”类并且位于#profile-list元素内的复选框。然后我们只需将它们的checked属性设置为true。我想,这和因为它可以是这样。)
Try this:
(So, first we select all check-boxes that are of the class "email-checkout" and are inside the #profile-list element. Then we just set their checked property to true. I assume, this is as fast as it can be.)
您始终可以为每个复选框提供一个选择/取消选择事件,该事件将从复选框添加/删除类,然后使用该类作为选择器。
You could always give each check box a select/deselect event that will add/remove a class from the checkbox, then use the class as the selector.
您可以在集合上使用
.each()
来使用元素直接,如下所示:另请注意上面删除
:not(:checked)
...如果您要检查所有这些,那么该选择器比实际检查它们更昂贵。更重要的是this.checked = true;
比$(elements[i]).attr('checked', 'checked'); 便宜非常
每次都会发生。You can use a
.each()
on the set to use the elements directly, like this:Also note the removal of
:not(:checked)
above...if you're going to check them all, that selector is more expensive that actually checking them anyway. More importantly is thatthis.checked = true;
is tremendously cheaper than$(elements[i]).attr('checked', 'checked');
which happens every time.您对此进行了简介吗?获取元素或循环遍历元素花费的时间太长?真正加速代码的唯一方法是分析和修复缓慢的部分。
FWIW,我会尝试
看看会发生什么。
Did you profile this? What is taking too long, getting the elements or looping over them? The only way to really speed up code is to profile and fix the slow parts.
FWIW, I would try
and see what happens.
添加 onlclick 复选框
Add an onlclick on the checkbox