Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Work around for live filtering 1500+ items with jQuery in Chrome

I'm being bitten by the Chrome/Webkit 71305 bug where un-hiding a large number of nodes causes Chrome to hang. (Also occurs in Safari).

I am filtering a list item that will be in a drop down menu with the following:

jQuery.expr[':'].Contains = function(a, i, m) {
    return $.trim((a.textContent || a.innerText || "")).toUpperCase().indexOf(m[3].toUpperCase()) == 0;
};

var input = $('input');
var container = $('ul');

input.keyup(function(e) {
    var filter = $.trim(input.val());

    if (filter.length > 0) {
        // Show matches.
        container.find("li:Contains(" + filter + ")").css("display", "block");
        container.find("li:not(:Contains(" + filter + "))").css("display", "none");
    }
    else {
        container.find('li').css("display", "block");
    }
});

Snippet of the markup:

<input type="text" />
<ul>  
    <li>
        <div>
            <span title="93252"><label><input type="checkbox">3G</label></span>
        </div>
    </li>
</ul>

The time it takes for the Javascript to execute is negligible. It's when Chrome needs to redraw the elements after deleting the text in the input that it hangs. Does not happen in FF6/IE7-9.

I made a JSFiddle to illustrate the issue: http://jsfiddle.net/uUk7S/17/show/

Is there another approach I can take rather than hiding and showing the elements that will not cause Chrome to hang? I have tried cloning the ul, processing in the clone and replacing the ul in the DOM completely with the clone, but am hoping there's a better way as this is significantly slower in IE.

like image 856
Soliah Avatar asked Aug 30 '11 05:08

Soliah


1 Answers

Have you tried other css possibility for hiding the elements?

Using css props like a switch of visibility? Or a switch between height:auto and height:0;overflow-y:hidden;?

I made a little example here, it's using .css({"visibility":"visible","height":"auto"}); to show and ({"visibility":"hidden","height":"0"}) to hide. And it seems to work fine in chrome in the few test I did.

EDIT: Even better here , you just have to use .css("visibility","visible"); and .css("visibility","hidden");. The use of li[style~="hidden;"]{height:0;} is doing the height modification for you.

like image 185
Py. Avatar answered Nov 06 '22 20:11

Py.