开发者

Chrome hangs when using javascript to check many checkboxes, while firefox does it instantly

开发者 https://www.devze.com 2023-02-04 22:58 出处:网络
I\'m using an asp:Repeater server side control that contains a table as it\'s repeatable item.One of the td tags in the table contains a checkbox.In the header of the repeater I have a checkbox with i

I'm using an asp:Repeater server side control that contains a table as it's repeatable item. One of the td tags in the table contains a checkbox. In the header of the repeater I have a checkbox with id="selectAllCheck".

I have the following javascript code

    var checkBox = document.getElementById('selectAllCheck');

    function changeAll() {
        if (checkBox.checked == 1) {
            $('input:checkbox').attr('checked', "checked");
        }
        else {
            $('input:checkbox').attr('checked', "");
        }
    }

    checkBox.onchange = changeAll;

This works just fine in firefox, instantly all the checkboxes are either checked or unchecked when necessary. However, in chrome it takes about 10 seconds. I do have about 250 checkboxes on the page by the way, but even putting that number down to only 开发者_JAVA百科15, I can see that it is still not instant with chrome, but much faster.

If anyone has encountered this problem before, seen any articles related to this problem, or knows how to solve this problem I would be very thankful.

EDIT: Posted the page

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentMain" Runat="Server">
<form id="webForm" runat="server">
    <asp:Label ID="sourceLabel" runat="server" AssociatedControlID="sourceList" Text="Source"></asp:Label>
    <asp:DropDownList ID="sourceList" runat="server" />&nbsp;
    <asp:Button ID="showButton" runat="server" Text="View" />
    <asp:Repeater ID="Repeater_DIBS" runat="server">
        <HeaderTemplate>
            <table>
            <tr><th><input type="checkbox" id="selectAllCheck" /> (un)check All</th>    <th>SourceID</th><th>FieldID</th><th>Source Indicator</th><th>Date Data Updated</th>   <th>Message</th></tr>
        </HeaderTemplate>
        <ItemTemplate>
            <tr>
                <td style='width:1%;white-space:nowrap;'><input type='checkbox' class='checkBoxes' /></td>
                <td style='width:1%;white-space:nowrap;'><%# Eval("SourceID") %></td>
                <td style='width:1%;white-space:nowrap;'><%# Eval("FieldID") %></td>
                <td class='indicator' style='width:1%;white-space:nowrap;'><%# Eval("SourceIndicator") %></td>
                <td style='width:1%;white-space:nowrap;'><%# Eval("DateDataUpdated") %></td>
                <td style='width:1%;white-space:nowrap;' class='status'></td>
            </tr>
        </ItemTemplate>

        <FooterTemplate>
            </table>
        </FooterTemplate>
    </asp:Repeater>
</form>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentJS" Runat="Server">
    <script type="text/javascript">
    $("#selectAllCheck").change(function () {
        if (this.checked) {
            $("input:checkbox.checkBoxes").attr("checked", "checked");
        }
        else {
            $("input:checkbox.checkBoxes").removeAttr("checked");
        }
    });

</script>
</asp:Content>


I think it's a bug in Chrome. The more checkboxes you have on a page, the slower the process gets. When you have around 500, the speed is ok. The problem is that when you get over 1000, the process to check all the boxes exponentially gets larger. In IE9 and FF4, this process does not matter. Even if you did not use jQuery and try to use straight js, you end up with Chrome getting slower the more checkboxes you use on a page.

Try limiting the number of checkboxes if possible.


You are selecting all the checkboxes in the page. Instead of this assign a class to all the child checkboxes and toggle the checked property of those textboxes. Also specify a parent element so that the search will be more specific. Something like

$("#chkAll").change(function(){
    if (this.checked) {
        $("#containerid input:checkbox.yourclass").attr("checked", "checked");
    }
    else {
        $("#containerid input:checkbox.yourclass").removeAttr("checked");
    }
});


try this refactoring and it should speed things up:

$(function() {
    $("#selectAllCheck").click(function(){
        $("input:checkbox:not(#selectAllCheck)").attr("checked", $(this).is(":checked"));
    });
});

binds the event to #selectAllCheck and checks all remaining checkboxes.


example here: http://jsfiddle.net/mDGzW/1/

works instant in Chrome....


Do not look up all of the checkboxes all of the time. If they are not dynamic, there is no reason to do it. It takes the browser a good amount of time to always look through the DOM to find the elements. Do it once and keep the reference.

Also the best selector you can use is just a classname in this case. The "input:checkbox" look up is a lot slower than just looking at the class.

Basic idea:

  (function(){

    var cbs = $(".cb");

    $("#checkall").click(
      function(){
         var state = this.checked;
         cbs.attr("checked", state);
      }
    )

  })();


I'd use a attr / removeAttr:

$(document).ready(function(){
    $('#selectAllCheck').click(function(){
            if($(this).is(':checked')) {
                $('input:checkbox').attr('checked', 'checked');
            }
            else {
            $('input:checkbox').removeAttr('checked');
            }
     });
});


A few minor performance tweaks:

http://jsfiddle.net/H9kK9/2/

  • Cache your list of checkboxes upfront, so the expensive DOM query is already finished when a user triggers onChange
  • Use the native "checked = true/false" instead of jQuery's prop/attr wrapper, to save on overhead. Checked is a very stable, old DOM property, and you should feel comfortable setting it on a DOM element without jQuery's help.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号