选择大量复选框和取消选择它们的最快方法是什么?

rba*_*all 5 javascript performance jquery

因为我使用jQuery 1.3+除了一次定时测试之外都使用它.另一个是我在2000年后期发现的普通javascript.我停止了那条路,因为它需要大约150秒来运行测试.我已经阅读了很多与选择单个元素相关的jQuery优化网页.'#id'是使用它的最佳情况,但现在我遇到了在一个包含多个复选框列的相当大的表检查一列中的所有复选框的问题.

我所做的是设置一个页面,创建20,000个表行和两个复选框列.目标是检查第二列是否花了多长时间,然后取消选中它们,看看花了多长时间.显然我们想要最短的时间.我只使用IE6和7,在我的情况下,我的所有用户都会这样做.

你说20000行?这就是我所说的,但这是生产(从我手中),现在改变为时已晚.我只是试着在时钟上留下1秒的冰雹玛丽.此外,我了解到input.chkbox不是最快的选择器(对于IE7)!:)

问题是,是否有更好的方法来执行此jQuery或其他方式?我喜欢它在我的机器上运行不到半秒钟.

所以你不必重新输入我已经完成的所有废话,这是我提出的测试内容:

4月14日上午更新,包括进一步的时间试验:

<form id="form1" runat="server">
<div>           
        <a href="#" id="one">input[id^='chkbox'][type='checkbox']</a><br />
        <a href="#" id="two">#myTable tr[id^='row'] input[id^='chkbox'][type='checkbox']</a><br />
        <a href="#" id="three">#myTable tr.myRow input[id^='chkbox'][type='checkbox']</a><br />
        <a href="#" id="four">tr.myRow input[id^='chkbox'][type='checkbox']</a><br />
        <a href="#" id="five">input[id^='chkbox']</a><br />
        <a href="#" id="six">.chkbox</a><br />
        <a href="#" id="seven">input.chkbox</a><br />
        <a href="#" id="eight">#myTable input.chkbox</a><br />

        <a href="#" id="nine">"input.chkbox", "tr"</a><br />
        <a href="#" id="nine1">"input.chkbox", "tr.myRow"</a><br />
        <a href="#" id="nine2">"input.chkbox", "#form1"</a><br />
        <a href="#" id="nine3">"input.chkbox", "#myTable"</a><br />

        <a href="#" id="ten">input[name=chkbox]</a><br />
        <a href="#" id="ten1">"input[name=chkbox]", "tr.myRow"</a><br />
        <a href="#" id="ten2">"input[name=chkbox]", "#form1"</a><br />
        <a href="#" id="ten3">"input[name=chkbox]", "#myTable"</a><br />

        <a href="#" id="ten4">"input[name=chkbox]", $("#form1")</a><br />
        <a href="#" id="ten5">"input[name=chkbox]", $("#myTable")</a><br />

        <a href="#" id="eleven">input[name='chkbox']:checkbox</a><br />
        <a href="#" id="twelve">:checkbox</a><br />
        <a href="#" id="twelve1">input:checkbox</a><br />
        <a href="#" id="thirteen">input[type=checkbox]</a><br />

        <div>
            <input type="text" id="goBox" /> <button id="go">Go!</button>
            <div id="goBoxTook"></div>
        </div>

        <table id="myTable">
            <tr id="headerRow"><th>Row #</th><th>Checkboxes o' fun!</th><th>Don't check these!</th></tr>
            <% for(int i = 0; i < 20000;i++) { %>
            <tr id="row<%= i %>" class="myRow">
                <td><%= i %> Row</td>
                <td>
                    <input type="checkbox" id="chkbox<%= i %>" name="chkbox" class="chkbox" />
                </td>
                <td>
                    <input type="checkbox" id="otherBox<%= i %>" name="otherBox" class="otherBox" />
                </td>
            </tr>
            <% } %>
        </table>
</div>
        <script type="text/javascript" src="<%= ResolveUrl("~/") %>Javascript/jquery.1.3.1.min.js"></script>
        <script type="text/javascript">

            $(function() {                  
                function run(selectorText, el) {                    
                    var start = new Date();                     
                    $(selectorText).attr("checked", true);                              
                    var end = new Date();
                    var timeElapsed = end-start;
                    $(el).after("<br />Checking Took " + timeElapsed + "ms");

                    start = new Date();                     
                    $(selectorText).attr("checked", false);                             
                    end = new Date();
                    timeElapsed = end-start;
                    $(el).after("<br />Unchecking Took " + timeElapsed + "ms");
                }       

                function runWithContext(selectorText, context, el) {                    
                    var start = new Date();                     
                    $(selectorText, context).attr("checked", true);                             
                    var end = new Date();
                    var timeElapsed = end-start;
                    $(el).after("<br />Checking Took " + timeElapsed + "ms");

                    start = new Date();                     
                    $(selectorText, context).attr("checked", false);                                
                    end = new Date();
                    timeElapsed = end-start;
                    $(el).after("<br />Unchecking Took " + timeElapsed + "ms");
                }

                $("#one").click(function() {                        
                    run("input[id^='chkbox'][type='checkbox']", this);
                });

                $("#two").click(function() {
                    run("#myTable tr[id^='row'] input[id^='chkbox'][type='checkbox']", this);
                });

                $("#three").click(function() {
                    run("#myTable tr.myRow input[id^='chkbox'][type='checkbox']", this);
                });

                $("#four").click(function() {
                    run("tr.myRow input[id^='chkbox'][type='checkbox']", this);
                });

                $("#five").click(function() {
                    run("input[id^='chkbox']", this);
                });

                $("#six").click(function() {
                    run(".chkbox", this);
                });

                $("#seven").click(function() {
                    run("input.chkbox", this);
                });

                $("#eight").click(function() {
                    run("#myTable input.chkbox", this);
                });

                $("#nine").click(function() {
                    runWithContext("input.chkbox", "tr", this);
                });


                $("#nine1").click(function() {
                    runWithContext("input.chkbox", "tr.myRow", this);
                });
                $("#nine2").click(function() {
                    runWithContext("input.chkbox", "#form1", this);
                });
                $("#nine3").click(function() {
                    runWithContext("input.chkbox", "#myTable", this);
                });

                $("#ten").click(function() {
                    run("input[name=chkbox]", this);
                });                 

                $("#ten1").click(function() {
                    runWithContext("input[name=chkbox]", "tr.myRow", this);
                });

                $("#ten2").click(function() {
                    runWithContext("input[name=chkbox]", "#form1", this);
                });

                $("#ten3").click(function() {
                    runWithContext("input[name=chkbox]", "#myTable", this);
                });

                $("#ten4").click(function() {
                    runWithContext("input[name=chkbox]", $("#form1"), this);
                });

                $("#ten5").click(function() {
                    runWithContext("input[name=chkbox]", $("#myTable"), this);
                });

                $("#eleven").click(function() {
                    run("input[name='chkbox']:checkbox", this);
                });

                $("#twelve").click(function() {
                    run(":checkbox", this);
                });

                $("#twelve1").click(function() {
                    run("input:checkbox", this);
                });

                $("#thirteen").click(function() {
                    run("input[type=checkbox]", this);
                });

                $('#go').click(function() {
                    run($('#goBox').val(), this);
                });
            });
        </script>
</form>
Run Code Online (Sandbox Code Playgroud)

rba*_*all 8

input [name = chkbox]作为IE7下我机器上最快的jQuery选择器进入.

Unchecking Took 2453ms
Checking Took 2438ms
Unchecking Took 2438ms
Checking Took 2437ms
Unchecking Took 2453ms
Checking Took 2438ms
Run Code Online (Sandbox Code Playgroud)

input.chkbox和...

Unchecking Took 2813ms
Checking Took 2797ms
Unchecking Took 2797ms
Checking Took 2797ms
Unchecking Took 2813ms
Checking Took 2797ms
Run Code Online (Sandbox Code Playgroud)

输入:checkbox.chkbox似乎并列

Unchecking Took 2797ms
Checking Took 2797ms
Unchecking Took 2813ms
Checking Took 2781ms
Run Code Online (Sandbox Code Playgroud)

.chkbox几乎是input.chkbox的两倍

Unchecking Took 4031ms
Checking Took 4062ms
Unchecking Took 4031ms
Checking Took 4062ms
Run Code Online (Sandbox Code Playgroud)

javascript for循环是迄今为止最糟糕的:

Checking Took 149797ms
Run Code Online (Sandbox Code Playgroud)

150秒!它也会锁定浏览器.这让我对jQuery印象深刻.老实说,我没想到它会那么慢.可能是因为我正在通过每个单独的元素,然后它必须找到...

这对我来说也很有意思:

输入[ID ^ = 'chkbox']

Unchecking Took 3031ms
Checking Took 3016ms
Run Code Online (Sandbox Code Playgroud)

更少的时间比:

输入[ID ^ = 'chkbox'] [式= '复选框']

Unchecking Took 3375ms
Checking Took 3344ms
Run Code Online (Sandbox Code Playgroud)

我想,因为我发布了更多的过滤器,它会更快.不!

指定更多路径到复选框会使速度变慢:

#myTable tr [id ^ ='row']输入[id ^ ='chkbox'] [type ='checkbox']

Checking Took 10422ms
Run Code Online (Sandbox Code Playgroud)

它甚至没有运行第二次取消检查,因为它问我是否要继续在我的计算机上运行脚本.疯!:P

4月14日上午更新:

有人提出设置上下文:我实际上做了一些这些并且让我很惊讶,并且反对很多人在IE7上在网上说过这些都比较慢!以下是我使用上面的快速选择器指定的几个不同上下文的时间:

"input.chkbox","tr"

Checking Took 8546ms
Run Code Online (Sandbox Code Playgroud)

"input.chkbox","tr.myRow"

Checking Took 8875ms
Run Code Online (Sandbox Code Playgroud)

"input.chkbox","#form1"

Unchecking Took 3032ms
Checking Took 3000ms
Run Code Online (Sandbox Code Playgroud)

"input.chkbox","#myTable"

Unchecking Took 2906ms
Checking Took 2875ms
Run Code Online (Sandbox Code Playgroud)

目前的赢家(仍然):输入[name = chkbox]

Unchecking Took 2469ms
Checking Took 2453ms
Run Code Online (Sandbox Code Playgroud)

"input [name = chkbox]","tr.myRow"

Checking Took 9547ms
Run Code Online (Sandbox Code Playgroud)

"input [name = chkbox]","#form1"

Unchecking Took 3140ms
Checking Took 3141ms
Run Code Online (Sandbox Code Playgroud)

"input [name = chkbox]","#myTable"

Unchecking Took 2985ms
Checking Took 2969ms
Run Code Online (Sandbox Code Playgroud)

更新2上午4/14

在我注意到http://beardscratchers.com/journal/jquery-its-all-about-context的语法差异后,我可能会有一个更好的.看起来这些并不相同,因为它们给出了稍好的时间,但仍然没有击败非上下文的选择器 - darn.

"input [name = chkbox]",$("#form1")

Unchecking Took 3078ms
Checking Took 3000ms
Unchecking Took 3078ms
Checking Took 3016ms
Run Code Online (Sandbox Code Playgroud)

"input [name = chkbox]",$("#myTable")

Unchecking Took 2938ms
Checking Took 2906ms
Unchecking Took 2938ms
Checking Took 2921ms
Run Code Online (Sandbox Code Playgroud)

更新3上午4/14

Russ希望我尝试这些,他们de /选择所有的盒子,但它又有趣:

:复选框

Unchecking Took 8328ms
Checking Took 6250ms
Run Code Online (Sandbox Code Playgroud)

输入:复选框

Unchecking Took 5016ms
Checking Took 5000ms
Run Code Online (Sandbox Code Playgroud)

- >最快?!?!输入[类型=复选框]

Unchecking Took 4969ms
Checking Took 4938ms
Run Code Online (Sandbox Code Playgroud)

第三个最快的事实是非常有趣的,因为这违背了我的想法.为什么不(至少IE7):复选框只使用type =复选框来实现更快的时间?这些都是非常接近的分数,但检查时间减少了62毫秒.另外,为什么前两个会有所不同?除了输入之外是否还有一个可以带有复选框的元素?


Cod*_*ain 5

我没有测试过这个,但你可以尝试在页面加载时构建一个复选框引用的数组[],然后在每次想要进行更改时简单地迭代它?

您需要在页面加载时支付性能成本,但它可能比每次遍历DOM更快.嘿,至少你会在用户"停机时间"中执行繁重的工作(人们找到并点击取消选择/选择选项需要多长时间).