user584583
user584583

Reputation: 1280

jquery checkbox slow, not sure how to fix

I have used firebug and IE profilers and can see what function in my code is causing the slowness. Being new to jquery, the recommendations that I have read online are not clear to me. I have made an example page that shows the slow behavior when you check or uncheck a check box. No surprise that this is fast using Chrome.

The function that is slow can be found on line 139.

$('.filters input').click( function() 

JSFiddle can be found here

The code is 122 KB and can be found here

UPDATE: if you know of any examples online that are similar in function and faster, please share.

Upvotes: 0

Views: 2307

Answers (2)

WickyNilliams
WickyNilliams

Reputation: 5308

i had a brief look through your code, but it was very hard to follow. it seemed as if you were looping through things many many times. i used a much simpler approach to get the list of all states.

your approach was * make a massive string which contained every class (possibly repeated multiple times) * chop it up into an array * loop through the array and remove duplicates

i simply took advantage of the fact that when you select something in jQuery you get a set rather than a single item. you can therefore apply changes to groups of object

$(document).ready(function () {
    //this will hold all our states
    var allStates = [];

    //cache filterable items for future use
    var $itemsToFilter = $(".filterThis");

    //loop through all items. children() is fast because it searches ONLY immediate children
    $itemsToFilter.children("li").each(function() {

        //use plain ol' JS, no need for jQuery to get attribute
        var cssClass = this.getAttribute("class");

        //if we haven't already added the class
        //then add to the array
        if(!allStates[cssClass]) {
             allStates[cssClass] = true;
        }
    });

    //create the container for our filter
    $('<ul class="filters"><\/ul>').insertBefore('.filterThis');

    //cache the filter container for use in the loop
    //otherwise we have to select it every time!
    var $filters = $(".filters");

    // then build the filter checkboxes based on all the class names
    for(var key in allStates) {
        //make sure it's a key we added
        if(allStates.hasOwnProperty(key)) {
            //add our filter
            $filters.append('<li><input class="dynamicFilterInput" type="checkbox" checked="checked" value="'+key+'" id="filterID'+key+'" /><label for="filterID'+key+'">'+key+'<\/label><\/li>');
        }
    }

    // now lets give those filters something to do
    $filters.find('input').click( function() {
        //cache the current checkbox
        var $this = $(this);

        //select our items to filter
        var $targets = $itemsToFilter.children("li." + $this.val());

        //if the filter is checked, show them all items, otherwise hide
        $this.is(":checked") ? $targets.show() : $targets.hide();

    });
});

FIDDLE: http://jsfiddle.net/bSr2X/6/

hope that's helpful :)

i noticed it ran quite a bit slower if you tried to slideup all the targets, this is because so many items are being animated at once. you may as well just hide them, since people will only see the ones at the top of the list slide in and out of view, so it's a waste of processor time :)

EDIT: i didn't add logic for show all, but that should be quite a trivial addition for you to make if you follow how i've done it above

Upvotes: 2

swatkins
swatkins

Reputation: 13630

You could use context with your selector:

$('.filters input', '#filters_container').click(function()...

this limits the element that jQuery has to look in when selecting elements. Instead of looking at every element in the page, it only looks inside your $('#filters_container') element.

Upvotes: 1

Related Questions